2011-10-26 20:13:33 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
2017-07-07 14:08:55 +02:00
|
|
|
* streamutil.c - utility functions for pg_basebackup, pg_receivewal and
|
2018-05-09 20:25:04 +02:00
|
|
|
* pg_recvlogical
|
2011-10-26 20:13:33 +02:00
|
|
|
*
|
|
|
|
* Author: Magnus Hagander <magnus@hagander.net>
|
|
|
|
*
|
2023-01-02 21:00:37 +01:00
|
|
|
* Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
|
2011-10-26 20:13:33 +02:00
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
|
|
|
* src/bin/pg_basebackup/streamutil.c
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
2012-12-13 13:59:13 +01:00
|
|
|
#include "postgres_fe.h"
|
2011-10-26 20:13:33 +02:00
|
|
|
|
2014-03-18 17:19:57 +01:00
|
|
|
#include <sys/time.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
Make WAL segment size configurable at initdb time.
For performance reasons a larger segment size than the default 16MB
can be useful. A larger segment size has two main benefits: Firstly,
in setups using archiving, it makes it easier to write scripts that
can keep up with higher amounts of WAL, secondly, the WAL has to be
written and synced to disk less frequently.
But at the same time large segment size are disadvantageous for
smaller databases. So far the segment size had to be configured at
compile time, often making it unrealistic to choose one fitting to a
particularly load. Therefore change it to a initdb time setting.
This includes a breaking changes to the xlogreader.h API, which now
requires the current segment size to be configured. For that and
similar reasons a number of binaries had to be taught how to recognize
the current segment size.
Author: Beena Emerson, editorialized by Andres Freund
Reviewed-By: Andres Freund, David Steele, Kuntal Ghosh, Michael
Paquier, Peter Eisentraut, Robert Hass, Tushar Ahuja
Discussion: https://postgr.es/m/CAOG9ApEAcQ--1ieKbhFzXSQPw_YLmepaa4hNdnY5+ZULpt81Mw@mail.gmail.com
2017-09-20 07:03:48 +02:00
|
|
|
#include "access/xlog_internal.h"
|
2020-08-10 18:22:54 +02:00
|
|
|
#include "common/connect.h"
|
2014-03-18 17:19:57 +01:00
|
|
|
#include "common/fe_memutils.h"
|
2018-04-07 23:45:39 +02:00
|
|
|
#include "common/file_perm.h"
|
2019-05-14 20:19:49 +02:00
|
|
|
#include "common/logging.h"
|
Remove arbitrary restrictions on password length.
This patch started out with the goal of harmonizing various arbitrary
limits on password length, but after awhile a better idea emerged:
let's just get rid of those fixed limits.
recv_password_packet() has an arbitrary limit on the packet size,
which we don't really need, so just drop it. (Note that this doesn't
really affect anything for MD5 or SCRAM password verification, since
those will hash the user's password to something shorter anyway.
It does matter for auth methods that require a cleartext password.)
Likewise remove the arbitrary error condition in pg_saslprep().
The remaining limits are mostly in client-side code that prompts
for passwords. To improve those, refactor simple_prompt() so that
it allocates its own result buffer that can be made as big as
necessary. Actually, it proves best to make a separate routine
pg_get_line() that has essentially the semantics of fgets(), except
that it allocates a suitable result buffer and hence will never
return a truncated line. (pg_get_line has a lot of potential
applications to replace randomly-sized fgets buffers elsewhere,
but I'll leave that for another patch.)
I built pg_get_line() atop stringinfo.c, which requires moving
that code to src/common/; but that seems fine since it was a poor
fit for src/port/ anyway.
This patch is mostly mine, but it owes a good deal to Nathan Bossart
who pressed for a solution to the password length problem and
created a predecessor patch. Also thanks to Peter Eisentraut and
Stephen Frost for ideas and discussion.
Discussion: https://postgr.es/m/09512C4F-8CB9-4021-B455-EF4C4F0D55A0@amazon.com
2020-09-04 02:09:18 +02:00
|
|
|
#include "common/string.h"
|
2014-03-18 17:19:57 +01:00
|
|
|
#include "datatype/timestamp.h"
|
2017-10-02 00:36:14 +02:00
|
|
|
#include "port/pg_bswap.h"
|
|
|
|
#include "pqexpbuffer.h"
|
2019-10-23 06:08:53 +02:00
|
|
|
#include "receivelog.h"
|
|
|
|
#include "streamutil.h"
|
2011-10-26 20:13:33 +02:00
|
|
|
|
2015-07-12 22:06:27 +02:00
|
|
|
#define ERRCODE_DUPLICATE_OBJECT "42710"
|
|
|
|
|
2023-04-03 07:13:52 +02:00
|
|
|
int WalSegSz;
|
Make WAL segment size configurable at initdb time.
For performance reasons a larger segment size than the default 16MB
can be useful. A larger segment size has two main benefits: Firstly,
in setups using archiving, it makes it easier to write scripts that
can keep up with higher amounts of WAL, secondly, the WAL has to be
written and synced to disk less frequently.
But at the same time large segment size are disadvantageous for
smaller databases. So far the segment size had to be configured at
compile time, often making it unrealistic to choose one fitting to a
particularly load. Therefore change it to a initdb time setting.
This includes a breaking changes to the xlogreader.h API, which now
requires the current segment size to be configured. For that and
similar reasons a number of binaries had to be taught how to recognize
the current segment size.
Author: Beena Emerson, editorialized by Andres Freund
Reviewed-By: Andres Freund, David Steele, Kuntal Ghosh, Michael
Paquier, Peter Eisentraut, Robert Hass, Tushar Ahuja
Discussion: https://postgr.es/m/CAOG9ApEAcQ--1ieKbhFzXSQPw_YLmepaa4hNdnY5+ZULpt81Mw@mail.gmail.com
2017-09-20 07:03:48 +02:00
|
|
|
|
2018-04-07 23:45:39 +02:00
|
|
|
static bool RetrieveDataDirCreatePerm(PGconn *conn);
|
|
|
|
|
Make WAL segment size configurable at initdb time.
For performance reasons a larger segment size than the default 16MB
can be useful. A larger segment size has two main benefits: Firstly,
in setups using archiving, it makes it easier to write scripts that
can keep up with higher amounts of WAL, secondly, the WAL has to be
written and synced to disk less frequently.
But at the same time large segment size are disadvantageous for
smaller databases. So far the segment size had to be configured at
compile time, often making it unrealistic to choose one fitting to a
particularly load. Therefore change it to a initdb time setting.
This includes a breaking changes to the xlogreader.h API, which now
requires the current segment size to be configured. For that and
similar reasons a number of binaries had to be taught how to recognize
the current segment size.
Author: Beena Emerson, editorialized by Andres Freund
Reviewed-By: Andres Freund, David Steele, Kuntal Ghosh, Michael
Paquier, Peter Eisentraut, Robert Hass, Tushar Ahuja
Discussion: https://postgr.es/m/CAOG9ApEAcQ--1ieKbhFzXSQPw_YLmepaa4hNdnY5+ZULpt81Mw@mail.gmail.com
2017-09-20 07:03:48 +02:00
|
|
|
/* SHOW command for replication connection was introduced in version 10 */
|
|
|
|
#define MINIMUM_VERSION_FOR_SHOW_CMD 100000
|
|
|
|
|
2018-04-07 23:45:39 +02:00
|
|
|
/*
|
|
|
|
* Group access is supported from version 11.
|
|
|
|
*/
|
|
|
|
#define MINIMUM_VERSION_FOR_GROUP_ACCESS 110000
|
|
|
|
|
2011-10-26 20:13:33 +02:00
|
|
|
const char *progname;
|
2013-02-25 13:48:27 +01:00
|
|
|
char *connection_string = NULL;
|
2011-10-26 20:13:33 +02:00
|
|
|
char *dbhost = NULL;
|
|
|
|
char *dbuser = NULL;
|
|
|
|
char *dbport = NULL;
|
2014-03-18 17:19:57 +01:00
|
|
|
char *dbname = NULL;
|
2011-10-26 20:13:33 +02:00
|
|
|
int dbgetpassword = 0; /* 0=auto, -1=never, 1=always */
|
Remove arbitrary restrictions on password length.
This patch started out with the goal of harmonizing various arbitrary
limits on password length, but after awhile a better idea emerged:
let's just get rid of those fixed limits.
recv_password_packet() has an arbitrary limit on the packet size,
which we don't really need, so just drop it. (Note that this doesn't
really affect anything for MD5 or SCRAM password verification, since
those will hash the user's password to something shorter anyway.
It does matter for auth methods that require a cleartext password.)
Likewise remove the arbitrary error condition in pg_saslprep().
The remaining limits are mostly in client-side code that prompts
for passwords. To improve those, refactor simple_prompt() so that
it allocates its own result buffer that can be made as big as
necessary. Actually, it proves best to make a separate routine
pg_get_line() that has essentially the semantics of fgets(), except
that it allocates a suitable result buffer and hence will never
return a truncated line. (pg_get_line has a lot of potential
applications to replace randomly-sized fgets buffers elsewhere,
but I'll leave that for another patch.)
I built pg_get_line() atop stringinfo.c, which requires moving
that code to src/common/; but that seems fine since it was a poor
fit for src/port/ anyway.
This patch is mostly mine, but it owes a good deal to Nathan Bossart
who pressed for a solution to the password length problem and
created a predecessor patch. Also thanks to Peter Eisentraut and
Stephen Frost for ideas and discussion.
Discussion: https://postgr.es/m/09512C4F-8CB9-4021-B455-EF4C4F0D55A0@amazon.com
2020-09-04 02:09:18 +02:00
|
|
|
static char *password = NULL;
|
2011-10-26 20:13:33 +02:00
|
|
|
PGconn *conn = NULL;
|
|
|
|
|
2012-05-27 11:05:24 +02:00
|
|
|
/*
|
|
|
|
* Connect to the server. Returns a valid PGconn pointer if connected,
|
|
|
|
* or NULL on non-permanent error. On permanent error, the function will
|
|
|
|
* call exit(1) directly.
|
|
|
|
*/
|
2011-10-26 20:13:33 +02:00
|
|
|
PGconn *
|
|
|
|
GetConnection(void)
|
|
|
|
{
|
|
|
|
PGconn *tmpconn;
|
2013-02-25 13:48:27 +01:00
|
|
|
int argcount = 7; /* dbname, replication, fallback_app_name,
|
|
|
|
* host, user, port, password */
|
2011-10-26 20:13:33 +02:00
|
|
|
int i;
|
|
|
|
const char **keywords;
|
|
|
|
const char **values;
|
2012-05-22 16:02:47 +02:00
|
|
|
const char *tmpparam;
|
2013-11-15 23:27:41 +01:00
|
|
|
bool need_password;
|
2013-02-25 13:48:27 +01:00
|
|
|
PQconninfoOption *conn_opts = NULL;
|
|
|
|
PQconninfoOption *conn_opt;
|
|
|
|
char *err_msg = NULL;
|
|
|
|
|
2016-08-08 16:07:46 +02:00
|
|
|
/* pg_recvlogical uses dbname only; others use connection_string only. */
|
|
|
|
Assert(dbname == NULL || connection_string == NULL);
|
|
|
|
|
2013-02-25 13:48:27 +01:00
|
|
|
/*
|
|
|
|
* Merge the connection info inputs given in form of connection string,
|
|
|
|
* options and default values (dbname=replication, replication=true, etc.)
|
2016-08-08 16:07:46 +02:00
|
|
|
* Explicitly discard any dbname value in the connection string;
|
|
|
|
* otherwise, PQconnectdbParams() would interpret that value as being
|
|
|
|
* itself a connection string.
|
2013-02-25 13:48:27 +01:00
|
|
|
*/
|
|
|
|
i = 0;
|
|
|
|
if (connection_string)
|
|
|
|
{
|
|
|
|
conn_opts = PQconninfoParse(connection_string, &err_msg);
|
|
|
|
if (conn_opts == NULL)
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("%s", err_msg);
|
2013-02-25 13:48:27 +01:00
|
|
|
|
|
|
|
for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
|
|
|
|
{
|
2016-08-08 16:07:46 +02:00
|
|
|
if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
|
|
|
|
strcmp(conn_opt->keyword, "dbname") != 0)
|
2013-02-25 13:48:27 +01:00
|
|
|
argcount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
|
|
|
|
values = pg_malloc0((argcount + 1) * sizeof(*values));
|
|
|
|
|
|
|
|
for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
|
|
|
|
{
|
2016-08-08 16:07:46 +02:00
|
|
|
if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
|
|
|
|
strcmp(conn_opt->keyword, "dbname") != 0)
|
2013-02-25 13:48:27 +01:00
|
|
|
{
|
|
|
|
keywords[i] = conn_opt->keyword;
|
|
|
|
values[i] = conn_opt->val;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
|
|
|
|
values = pg_malloc0((argcount + 1) * sizeof(*values));
|
|
|
|
}
|
|
|
|
|
|
|
|
keywords[i] = "dbname";
|
2014-03-18 17:19:57 +01:00
|
|
|
values[i] = dbname == NULL ? "replication" : dbname;
|
2013-02-25 13:48:27 +01:00
|
|
|
i++;
|
|
|
|
keywords[i] = "replication";
|
2014-03-18 17:19:57 +01:00
|
|
|
values[i] = dbname == NULL ? "true" : "database";
|
2013-02-25 13:48:27 +01:00
|
|
|
i++;
|
|
|
|
keywords[i] = "fallback_application_name";
|
|
|
|
values[i] = progname;
|
|
|
|
i++;
|
2011-10-26 20:13:33 +02:00
|
|
|
|
|
|
|
if (dbhost)
|
|
|
|
{
|
|
|
|
keywords[i] = "host";
|
|
|
|
values[i] = dbhost;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (dbuser)
|
|
|
|
{
|
|
|
|
keywords[i] = "user";
|
|
|
|
values[i] = dbuser;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
if (dbport)
|
|
|
|
{
|
|
|
|
keywords[i] = "port";
|
|
|
|
values[i] = dbport;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
2013-11-15 23:27:41 +01:00
|
|
|
/* If -W was given, force prompt for password, but only the first time */
|
Remove arbitrary restrictions on password length.
This patch started out with the goal of harmonizing various arbitrary
limits on password length, but after awhile a better idea emerged:
let's just get rid of those fixed limits.
recv_password_packet() has an arbitrary limit on the packet size,
which we don't really need, so just drop it. (Note that this doesn't
really affect anything for MD5 or SCRAM password verification, since
those will hash the user's password to something shorter anyway.
It does matter for auth methods that require a cleartext password.)
Likewise remove the arbitrary error condition in pg_saslprep().
The remaining limits are mostly in client-side code that prompts
for passwords. To improve those, refactor simple_prompt() so that
it allocates its own result buffer that can be made as big as
necessary. Actually, it proves best to make a separate routine
pg_get_line() that has essentially the semantics of fgets(), except
that it allocates a suitable result buffer and hence will never
return a truncated line. (pg_get_line has a lot of potential
applications to replace randomly-sized fgets buffers elsewhere,
but I'll leave that for another patch.)
I built pg_get_line() atop stringinfo.c, which requires moving
that code to src/common/; but that seems fine since it was a poor
fit for src/port/ anyway.
This patch is mostly mine, but it owes a good deal to Nathan Bossart
who pressed for a solution to the password length problem and
created a predecessor patch. Also thanks to Peter Eisentraut and
Stephen Frost for ideas and discussion.
Discussion: https://postgr.es/m/09512C4F-8CB9-4021-B455-EF4C4F0D55A0@amazon.com
2020-09-04 02:09:18 +02:00
|
|
|
need_password = (dbgetpassword == 1 && !password);
|
2013-11-15 23:27:41 +01:00
|
|
|
|
2013-11-22 03:46:43 +01:00
|
|
|
do
|
2011-10-26 20:13:33 +02:00
|
|
|
{
|
2013-11-15 23:27:41 +01:00
|
|
|
/* Get a new password if appropriate */
|
|
|
|
if (need_password)
|
|
|
|
{
|
2022-06-16 21:50:56 +02:00
|
|
|
free(password);
|
Remove arbitrary restrictions on password length.
This patch started out with the goal of harmonizing various arbitrary
limits on password length, but after awhile a better idea emerged:
let's just get rid of those fixed limits.
recv_password_packet() has an arbitrary limit on the packet size,
which we don't really need, so just drop it. (Note that this doesn't
really affect anything for MD5 or SCRAM password verification, since
those will hash the user's password to something shorter anyway.
It does matter for auth methods that require a cleartext password.)
Likewise remove the arbitrary error condition in pg_saslprep().
The remaining limits are mostly in client-side code that prompts
for passwords. To improve those, refactor simple_prompt() so that
it allocates its own result buffer that can be made as big as
necessary. Actually, it proves best to make a separate routine
pg_get_line() that has essentially the semantics of fgets(), except
that it allocates a suitable result buffer and hence will never
return a truncated line. (pg_get_line has a lot of potential
applications to replace randomly-sized fgets buffers elsewhere,
but I'll leave that for another patch.)
I built pg_get_line() atop stringinfo.c, which requires moving
that code to src/common/; but that seems fine since it was a poor
fit for src/port/ anyway.
This patch is mostly mine, but it owes a good deal to Nathan Bossart
who pressed for a solution to the password length problem and
created a predecessor patch. Also thanks to Peter Eisentraut and
Stephen Frost for ideas and discussion.
Discussion: https://postgr.es/m/09512C4F-8CB9-4021-B455-EF4C4F0D55A0@amazon.com
2020-09-04 02:09:18 +02:00
|
|
|
password = simple_prompt("Password: ", false);
|
2013-11-15 23:27:41 +01:00
|
|
|
need_password = false;
|
|
|
|
}
|
2011-10-26 20:13:33 +02:00
|
|
|
|
2013-11-15 23:27:41 +01:00
|
|
|
/* Use (or reuse, on a subsequent connection) password if we have it */
|
Remove arbitrary restrictions on password length.
This patch started out with the goal of harmonizing various arbitrary
limits on password length, but after awhile a better idea emerged:
let's just get rid of those fixed limits.
recv_password_packet() has an arbitrary limit on the packet size,
which we don't really need, so just drop it. (Note that this doesn't
really affect anything for MD5 or SCRAM password verification, since
those will hash the user's password to something shorter anyway.
It does matter for auth methods that require a cleartext password.)
Likewise remove the arbitrary error condition in pg_saslprep().
The remaining limits are mostly in client-side code that prompts
for passwords. To improve those, refactor simple_prompt() so that
it allocates its own result buffer that can be made as big as
necessary. Actually, it proves best to make a separate routine
pg_get_line() that has essentially the semantics of fgets(), except
that it allocates a suitable result buffer and hence will never
return a truncated line. (pg_get_line has a lot of potential
applications to replace randomly-sized fgets buffers elsewhere,
but I'll leave that for another patch.)
I built pg_get_line() atop stringinfo.c, which requires moving
that code to src/common/; but that seems fine since it was a poor
fit for src/port/ anyway.
This patch is mostly mine, but it owes a good deal to Nathan Bossart
who pressed for a solution to the password length problem and
created a predecessor patch. Also thanks to Peter Eisentraut and
Stephen Frost for ideas and discussion.
Discussion: https://postgr.es/m/09512C4F-8CB9-4021-B455-EF4C4F0D55A0@amazon.com
2020-09-04 02:09:18 +02:00
|
|
|
if (password)
|
2011-10-26 20:13:33 +02:00
|
|
|
{
|
2013-02-25 13:48:27 +01:00
|
|
|
keywords[i] = "password";
|
Simplify correct use of simple_prompt().
The previous API for this function had it returning a malloc'd string.
That meant that callers had to check for NULL return, which few of them
were doing, and it also meant that callers had to remember to free()
the string later, which required extra logic in most cases.
Instead, make simple_prompt() write into a buffer supplied by the caller.
Anywhere that the maximum required input length is reasonably small,
which is almost all of the callers, we can just use a local or static
array as the buffer instead of dealing with malloc/free.
A fair number of callers used "pointer == NULL" as a proxy for "haven't
requested the password yet". Maintaining the same behavior requires
adding a separate boolean flag for that, which adds back some of the
complexity we save by removing free()s. Nonetheless, this nets out
at a small reduction in overall code size, and considerably less code
than we would have had if we'd added the missing NULL-return checks
everywhere they were needed.
In passing, clean up the API comment for simple_prompt() and get rid
of a very-unnecessary malloc/free in its Windows code path.
This is nominally a bug fix, but it does not seem worth back-patching,
because the actual risk of an OOM failure in any of these places seems
pretty tiny, and all of them are client-side not server-side anyway.
This patch is by me, but it owes a great deal to Michael Paquier
who identified the problem and drafted a patch for fixing it the
other way.
Discussion: <CAB7nPqRu07Ot6iht9i9KRfYLpDaF2ZuUv5y_+72uP23ZAGysRg@mail.gmail.com>
2016-08-30 23:02:02 +02:00
|
|
|
values[i] = password;
|
2011-10-26 20:13:33 +02:00
|
|
|
}
|
2013-11-15 23:27:41 +01:00
|
|
|
else
|
2011-10-26 20:13:33 +02:00
|
|
|
{
|
2013-11-15 23:27:41 +01:00
|
|
|
keywords[i] = NULL;
|
|
|
|
values[i] = NULL;
|
2011-10-26 20:13:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
tmpconn = PQconnectdbParams(keywords, values, true);
|
|
|
|
|
2012-07-12 13:31:19 +02:00
|
|
|
/*
|
|
|
|
* If there is too little memory even to allocate the PGconn object
|
|
|
|
* and PQconnectdbParams returns NULL, we call exit(1) directly.
|
|
|
|
*/
|
|
|
|
if (!tmpconn)
|
2022-04-08 20:55:14 +02:00
|
|
|
pg_fatal("could not connect to server");
|
2012-07-12 13:31:19 +02:00
|
|
|
|
2013-11-15 23:27:41 +01:00
|
|
|
/* If we need a password and -w wasn't given, loop back and get one */
|
2011-10-26 20:13:33 +02:00
|
|
|
if (PQstatus(tmpconn) == CONNECTION_BAD &&
|
|
|
|
PQconnectionNeedsPassword(tmpconn) &&
|
|
|
|
dbgetpassword != -1)
|
|
|
|
{
|
2012-07-12 13:31:19 +02:00
|
|
|
PQfinish(tmpconn);
|
2013-11-15 23:27:41 +01:00
|
|
|
need_password = true;
|
2011-10-26 20:13:33 +02:00
|
|
|
}
|
2013-11-15 23:27:41 +01:00
|
|
|
}
|
2013-11-22 03:46:43 +01:00
|
|
|
while (need_password);
|
2011-10-26 20:13:33 +02:00
|
|
|
|
2013-11-15 23:27:41 +01:00
|
|
|
if (PQstatus(tmpconn) != CONNECTION_OK)
|
|
|
|
{
|
2020-11-07 22:15:52 +01:00
|
|
|
pg_log_error("%s", PQerrorMessage(tmpconn));
|
2013-11-15 23:27:41 +01:00
|
|
|
PQfinish(tmpconn);
|
2011-10-26 20:13:33 +02:00
|
|
|
free(values);
|
|
|
|
free(keywords);
|
2022-07-03 20:11:05 +02:00
|
|
|
PQconninfoFree(conn_opts);
|
2013-11-15 23:27:41 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
2011-10-26 20:13:33 +02:00
|
|
|
|
2013-11-15 23:27:41 +01:00
|
|
|
/* Connection ok! */
|
|
|
|
free(values);
|
|
|
|
free(keywords);
|
2022-07-03 20:11:05 +02:00
|
|
|
PQconninfoFree(conn_opts);
|
2013-11-15 23:27:41 +01:00
|
|
|
|
2018-03-18 13:08:25 +01:00
|
|
|
/*
|
|
|
|
* Set always-secure search path, so malicious users can't get control.
|
|
|
|
* The capacity to run normal SQL queries was added in PostgreSQL 10, so
|
|
|
|
* the search path cannot be changed (by us or attackers) on earlier
|
|
|
|
* versions.
|
|
|
|
*/
|
2018-04-26 03:50:29 +02:00
|
|
|
if (dbname != NULL && PQserverVersion(tmpconn) >= 100000)
|
Empty search_path in Autovacuum and non-psql/pgbench clients.
This makes the client programs behave as documented regardless of the
connect-time search_path and regardless of user-created objects. Today,
a malicious user with CREATE permission on a search_path schema can take
control of certain of these clients' queries and invoke arbitrary SQL
functions under the client identity, often a superuser. This is
exploitable in the default configuration, where all users have CREATE
privilege on schema "public".
This changes behavior of user-defined code stored in the database, like
pg_index.indexprs and pg_extension_config_dump(). If they reach code
bearing unqualified names, "does not exist" or "no schema has been
selected to create in" errors might appear. Users may fix such errors
by schema-qualifying affected names. After upgrading, consider watching
server logs for these errors.
The --table arguments of src/bin/scripts clients have been lax; for
example, "vacuumdb -Zt pg_am\;CHECKPOINT" performed a checkpoint. That
now fails, but for now, "vacuumdb -Zt 'pg_am(amname);CHECKPOINT'" still
performs a checkpoint.
Back-patch to 9.3 (all supported versions).
Reviewed by Tom Lane, though this fix strategy was not his first choice.
Reported by Arseniy Sharoglazov.
Security: CVE-2018-1058
2018-02-26 16:39:44 +01:00
|
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
|
|
|
|
res = PQexec(tmpconn, ALWAYS_SECURE_SEARCH_PATH_SQL);
|
|
|
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not clear search_path: %s",
|
|
|
|
PQerrorMessage(tmpconn));
|
Empty search_path in Autovacuum and non-psql/pgbench clients.
This makes the client programs behave as documented regardless of the
connect-time search_path and regardless of user-created objects. Today,
a malicious user with CREATE permission on a search_path schema can take
control of certain of these clients' queries and invoke arbitrary SQL
functions under the client identity, often a superuser. This is
exploitable in the default configuration, where all users have CREATE
privilege on schema "public".
This changes behavior of user-defined code stored in the database, like
pg_index.indexprs and pg_extension_config_dump(). If they reach code
bearing unqualified names, "does not exist" or "no schema has been
selected to create in" errors might appear. Users may fix such errors
by schema-qualifying affected names. After upgrading, consider watching
server logs for these errors.
The --table arguments of src/bin/scripts clients have been lax; for
example, "vacuumdb -Zt pg_am\;CHECKPOINT" performed a checkpoint. That
now fails, but for now, "vacuumdb -Zt 'pg_am(amname);CHECKPOINT'" still
performs a checkpoint.
Back-patch to 9.3 (all supported versions).
Reviewed by Tom Lane, though this fix strategy was not his first choice.
Reported by Arseniy Sharoglazov.
Security: CVE-2018-1058
2018-02-26 16:39:44 +01:00
|
|
|
PQclear(res);
|
|
|
|
PQfinish(tmpconn);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
PQclear(res);
|
|
|
|
}
|
|
|
|
|
2013-11-15 23:27:41 +01:00
|
|
|
/*
|
2017-02-23 20:04:43 +01:00
|
|
|
* Ensure we have the same value of integer_datetimes (now always "on") as
|
|
|
|
* the server we are connecting to.
|
2013-11-15 23:27:41 +01:00
|
|
|
*/
|
|
|
|
tmpparam = PQparameterStatus(tmpconn, "integer_datetimes");
|
|
|
|
if (!tmpparam)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not determine server setting for integer_datetimes");
|
2013-11-15 23:27:41 +01:00
|
|
|
PQfinish(tmpconn);
|
|
|
|
exit(1);
|
|
|
|
}
|
2012-05-22 16:02:47 +02:00
|
|
|
|
2013-11-15 23:27:41 +01:00
|
|
|
if (strcmp(tmpparam, "on") != 0)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("integer_datetimes compile flag does not match server");
|
2013-11-15 23:27:41 +01:00
|
|
|
PQfinish(tmpconn);
|
|
|
|
exit(1);
|
2011-10-26 20:13:33 +02:00
|
|
|
}
|
2013-11-15 23:27:41 +01:00
|
|
|
|
2018-04-07 23:45:39 +02:00
|
|
|
/*
|
|
|
|
* Retrieve the source data directory mode and use it to construct a umask
|
|
|
|
* for creating directories and files.
|
|
|
|
*/
|
|
|
|
if (!RetrieveDataDirCreatePerm(tmpconn))
|
|
|
|
{
|
|
|
|
PQfinish(tmpconn);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2013-11-15 23:27:41 +01:00
|
|
|
return tmpconn;
|
2011-10-26 20:13:33 +02:00
|
|
|
}
|
2014-03-18 17:19:57 +01:00
|
|
|
|
Make WAL segment size configurable at initdb time.
For performance reasons a larger segment size than the default 16MB
can be useful. A larger segment size has two main benefits: Firstly,
in setups using archiving, it makes it easier to write scripts that
can keep up with higher amounts of WAL, secondly, the WAL has to be
written and synced to disk less frequently.
But at the same time large segment size are disadvantageous for
smaller databases. So far the segment size had to be configured at
compile time, often making it unrealistic to choose one fitting to a
particularly load. Therefore change it to a initdb time setting.
This includes a breaking changes to the xlogreader.h API, which now
requires the current segment size to be configured. For that and
similar reasons a number of binaries had to be taught how to recognize
the current segment size.
Author: Beena Emerson, editorialized by Andres Freund
Reviewed-By: Andres Freund, David Steele, Kuntal Ghosh, Michael
Paquier, Peter Eisentraut, Robert Hass, Tushar Ahuja
Discussion: https://postgr.es/m/CAOG9ApEAcQ--1ieKbhFzXSQPw_YLmepaa4hNdnY5+ZULpt81Mw@mail.gmail.com
2017-09-20 07:03:48 +02:00
|
|
|
/*
|
|
|
|
* From version 10, explicitly set wal segment size using SHOW wal_segment_size
|
|
|
|
* since ControlFile is not accessible here.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
RetrieveWalSegSize(PGconn *conn)
|
|
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
char xlog_unit[3];
|
|
|
|
int xlog_val,
|
|
|
|
multiplier = 1;
|
|
|
|
|
|
|
|
/* check connection existence */
|
|
|
|
Assert(conn != NULL);
|
|
|
|
|
|
|
|
/* for previous versions set the default xlog seg size */
|
|
|
|
if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_SHOW_CMD)
|
|
|
|
{
|
|
|
|
WalSegSz = DEFAULT_XLOG_SEG_SIZE;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
res = PQexec(conn, "SHOW wal_segment_size");
|
|
|
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not send replication command \"%s\": %s",
|
|
|
|
"SHOW wal_segment_size", PQerrorMessage(conn));
|
Make WAL segment size configurable at initdb time.
For performance reasons a larger segment size than the default 16MB
can be useful. A larger segment size has two main benefits: Firstly,
in setups using archiving, it makes it easier to write scripts that
can keep up with higher amounts of WAL, secondly, the WAL has to be
written and synced to disk less frequently.
But at the same time large segment size are disadvantageous for
smaller databases. So far the segment size had to be configured at
compile time, often making it unrealistic to choose one fitting to a
particularly load. Therefore change it to a initdb time setting.
This includes a breaking changes to the xlogreader.h API, which now
requires the current segment size to be configured. For that and
similar reasons a number of binaries had to be taught how to recognize
the current segment size.
Author: Beena Emerson, editorialized by Andres Freund
Reviewed-By: Andres Freund, David Steele, Kuntal Ghosh, Michael
Paquier, Peter Eisentraut, Robert Hass, Tushar Ahuja
Discussion: https://postgr.es/m/CAOG9ApEAcQ--1ieKbhFzXSQPw_YLmepaa4hNdnY5+ZULpt81Mw@mail.gmail.com
2017-09-20 07:03:48 +02:00
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (PQntuples(res) != 1 || PQnfields(res) < 1)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields",
|
|
|
|
PQntuples(res), PQnfields(res), 1, 1);
|
Make WAL segment size configurable at initdb time.
For performance reasons a larger segment size than the default 16MB
can be useful. A larger segment size has two main benefits: Firstly,
in setups using archiving, it makes it easier to write scripts that
can keep up with higher amounts of WAL, secondly, the WAL has to be
written and synced to disk less frequently.
But at the same time large segment size are disadvantageous for
smaller databases. So far the segment size had to be configured at
compile time, often making it unrealistic to choose one fitting to a
particularly load. Therefore change it to a initdb time setting.
This includes a breaking changes to the xlogreader.h API, which now
requires the current segment size to be configured. For that and
similar reasons a number of binaries had to be taught how to recognize
the current segment size.
Author: Beena Emerson, editorialized by Andres Freund
Reviewed-By: Andres Freund, David Steele, Kuntal Ghosh, Michael
Paquier, Peter Eisentraut, Robert Hass, Tushar Ahuja
Discussion: https://postgr.es/m/CAOG9ApEAcQ--1ieKbhFzXSQPw_YLmepaa4hNdnY5+ZULpt81Mw@mail.gmail.com
2017-09-20 07:03:48 +02:00
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fetch xlog value and unit from the result */
|
2021-10-19 12:59:50 +02:00
|
|
|
if (sscanf(PQgetvalue(res, 0, 0), "%d%2s", &xlog_val, xlog_unit) != 2)
|
Make WAL segment size configurable at initdb time.
For performance reasons a larger segment size than the default 16MB
can be useful. A larger segment size has two main benefits: Firstly,
in setups using archiving, it makes it easier to write scripts that
can keep up with higher amounts of WAL, secondly, the WAL has to be
written and synced to disk less frequently.
But at the same time large segment size are disadvantageous for
smaller databases. So far the segment size had to be configured at
compile time, often making it unrealistic to choose one fitting to a
particularly load. Therefore change it to a initdb time setting.
This includes a breaking changes to the xlogreader.h API, which now
requires the current segment size to be configured. For that and
similar reasons a number of binaries had to be taught how to recognize
the current segment size.
Author: Beena Emerson, editorialized by Andres Freund
Reviewed-By: Andres Freund, David Steele, Kuntal Ghosh, Michael
Paquier, Peter Eisentraut, Robert Hass, Tushar Ahuja
Discussion: https://postgr.es/m/CAOG9ApEAcQ--1ieKbhFzXSQPw_YLmepaa4hNdnY5+ZULpt81Mw@mail.gmail.com
2017-09-20 07:03:48 +02:00
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("WAL segment size could not be parsed");
|
2020-04-17 03:45:08 +02:00
|
|
|
PQclear(res);
|
Make WAL segment size configurable at initdb time.
For performance reasons a larger segment size than the default 16MB
can be useful. A larger segment size has two main benefits: Firstly,
in setups using archiving, it makes it easier to write scripts that
can keep up with higher amounts of WAL, secondly, the WAL has to be
written and synced to disk less frequently.
But at the same time large segment size are disadvantageous for
smaller databases. So far the segment size had to be configured at
compile time, often making it unrealistic to choose one fitting to a
particularly load. Therefore change it to a initdb time setting.
This includes a breaking changes to the xlogreader.h API, which now
requires the current segment size to be configured. For that and
similar reasons a number of binaries had to be taught how to recognize
the current segment size.
Author: Beena Emerson, editorialized by Andres Freund
Reviewed-By: Andres Freund, David Steele, Kuntal Ghosh, Michael
Paquier, Peter Eisentraut, Robert Hass, Tushar Ahuja
Discussion: https://postgr.es/m/CAOG9ApEAcQ--1ieKbhFzXSQPw_YLmepaa4hNdnY5+ZULpt81Mw@mail.gmail.com
2017-09-20 07:03:48 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-04-17 03:45:08 +02:00
|
|
|
PQclear(res);
|
|
|
|
|
Make WAL segment size configurable at initdb time.
For performance reasons a larger segment size than the default 16MB
can be useful. A larger segment size has two main benefits: Firstly,
in setups using archiving, it makes it easier to write scripts that
can keep up with higher amounts of WAL, secondly, the WAL has to be
written and synced to disk less frequently.
But at the same time large segment size are disadvantageous for
smaller databases. So far the segment size had to be configured at
compile time, often making it unrealistic to choose one fitting to a
particularly load. Therefore change it to a initdb time setting.
This includes a breaking changes to the xlogreader.h API, which now
requires the current segment size to be configured. For that and
similar reasons a number of binaries had to be taught how to recognize
the current segment size.
Author: Beena Emerson, editorialized by Andres Freund
Reviewed-By: Andres Freund, David Steele, Kuntal Ghosh, Michael
Paquier, Peter Eisentraut, Robert Hass, Tushar Ahuja
Discussion: https://postgr.es/m/CAOG9ApEAcQ--1ieKbhFzXSQPw_YLmepaa4hNdnY5+ZULpt81Mw@mail.gmail.com
2017-09-20 07:03:48 +02:00
|
|
|
/* set the multiplier based on unit to convert xlog_val to bytes */
|
|
|
|
if (strcmp(xlog_unit, "MB") == 0)
|
|
|
|
multiplier = 1024 * 1024;
|
|
|
|
else if (strcmp(xlog_unit, "GB") == 0)
|
|
|
|
multiplier = 1024 * 1024 * 1024;
|
|
|
|
|
|
|
|
/* convert and set WalSegSz */
|
|
|
|
WalSegSz = xlog_val * multiplier;
|
|
|
|
|
|
|
|
if (!IsValidWalSegSize(WalSegSz))
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error(ngettext("WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte",
|
|
|
|
"WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes",
|
|
|
|
WalSegSz),
|
|
|
|
WalSegSz);
|
Make WAL segment size configurable at initdb time.
For performance reasons a larger segment size than the default 16MB
can be useful. A larger segment size has two main benefits: Firstly,
in setups using archiving, it makes it easier to write scripts that
can keep up with higher amounts of WAL, secondly, the WAL has to be
written and synced to disk less frequently.
But at the same time large segment size are disadvantageous for
smaller databases. So far the segment size had to be configured at
compile time, often making it unrealistic to choose one fitting to a
particularly load. Therefore change it to a initdb time setting.
This includes a breaking changes to the xlogreader.h API, which now
requires the current segment size to be configured. For that and
similar reasons a number of binaries had to be taught how to recognize
the current segment size.
Author: Beena Emerson, editorialized by Andres Freund
Reviewed-By: Andres Freund, David Steele, Kuntal Ghosh, Michael
Paquier, Peter Eisentraut, Robert Hass, Tushar Ahuja
Discussion: https://postgr.es/m/CAOG9ApEAcQ--1ieKbhFzXSQPw_YLmepaa4hNdnY5+ZULpt81Mw@mail.gmail.com
2017-09-20 07:03:48 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-04-07 23:45:39 +02:00
|
|
|
/*
|
|
|
|
* RetrieveDataDirCreatePerm
|
|
|
|
*
|
|
|
|
* This function is used to determine the privileges on the server's PG data
|
|
|
|
* directory and, based on that, set what the permissions will be for
|
|
|
|
* directories and files we create.
|
|
|
|
*
|
|
|
|
* PG11 added support for (optionally) group read/execute rights to be set on
|
|
|
|
* the data directory. Prior to PG11, only the owner was allowed to have rights
|
|
|
|
* on the data directory.
|
|
|
|
*/
|
|
|
|
static bool
|
|
|
|
RetrieveDataDirCreatePerm(PGconn *conn)
|
|
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
int data_directory_mode;
|
|
|
|
|
|
|
|
/* check connection existence */
|
|
|
|
Assert(conn != NULL);
|
|
|
|
|
|
|
|
/* for previous versions leave the default group access */
|
|
|
|
if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_GROUP_ACCESS)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
res = PQexec(conn, "SHOW data_directory_mode");
|
|
|
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not send replication command \"%s\": %s",
|
|
|
|
"SHOW data_directory_mode", PQerrorMessage(conn));
|
2018-04-07 23:45:39 +02:00
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (PQntuples(res) != 1 || PQnfields(res) < 1)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields",
|
|
|
|
PQntuples(res), PQnfields(res), 1, 1);
|
2018-04-07 23:45:39 +02:00
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sscanf(PQgetvalue(res, 0, 0), "%o", &data_directory_mode) != 1)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("group access flag could not be parsed: %s",
|
|
|
|
PQgetvalue(res, 0, 0));
|
2018-04-07 23:45:39 +02:00
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetDataDirectoryCreatePerm(data_directory_mode);
|
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-10-01 17:22:21 +02:00
|
|
|
/*
|
|
|
|
* Run IDENTIFY_SYSTEM through a given connection and give back to caller
|
|
|
|
* some result information if requested:
|
|
|
|
* - System identifier
|
2016-01-05 21:25:12 +01:00
|
|
|
* - Current timeline ID
|
|
|
|
* - Start LSN position
|
|
|
|
* - Database name (NULL in servers prior to 9.4)
|
2014-10-01 17:22:21 +02:00
|
|
|
*/
|
|
|
|
bool
|
|
|
|
RunIdentifySystem(PGconn *conn, char **sysid, TimeLineID *starttli,
|
|
|
|
XLogRecPtr *startpos, char **db_name)
|
|
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
uint32 hi,
|
|
|
|
lo;
|
|
|
|
|
|
|
|
/* Check connection existence */
|
|
|
|
Assert(conn != NULL);
|
|
|
|
|
|
|
|
res = PQexec(conn, "IDENTIFY_SYSTEM");
|
|
|
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not send replication command \"%s\": %s",
|
|
|
|
"IDENTIFY_SYSTEM", PQerrorMessage(conn));
|
2014-10-06 17:18:13 +02:00
|
|
|
|
|
|
|
PQclear(res);
|
2014-10-01 17:22:21 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (PQntuples(res) != 1 || PQnfields(res) < 3)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields",
|
|
|
|
PQntuples(res), PQnfields(res), 1, 3);
|
2014-10-06 17:18:13 +02:00
|
|
|
|
|
|
|
PQclear(res);
|
2014-10-01 17:22:21 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get system identifier */
|
|
|
|
if (sysid != NULL)
|
|
|
|
*sysid = pg_strdup(PQgetvalue(res, 0, 0));
|
|
|
|
|
|
|
|
/* Get timeline ID to start streaming from */
|
|
|
|
if (starttli != NULL)
|
|
|
|
*starttli = atoi(PQgetvalue(res, 0, 1));
|
|
|
|
|
|
|
|
/* Get LSN start position if necessary */
|
|
|
|
if (startpos != NULL)
|
|
|
|
{
|
|
|
|
if (sscanf(PQgetvalue(res, 0, 2), "%X/%X", &hi, &lo) != 2)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not parse write-ahead log location \"%s\"",
|
|
|
|
PQgetvalue(res, 0, 2));
|
2014-10-06 17:18:13 +02:00
|
|
|
|
|
|
|
PQclear(res);
|
2014-10-01 17:22:21 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
*startpos = ((uint64) hi) << 32 | lo;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get database name, only available in 9.4 and newer versions */
|
|
|
|
if (db_name != NULL)
|
|
|
|
{
|
2016-01-05 21:25:12 +01:00
|
|
|
*db_name = NULL;
|
|
|
|
if (PQserverVersion(conn) >= 90400)
|
|
|
|
{
|
|
|
|
if (PQnfields(res) < 4)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields",
|
|
|
|
PQntuples(res), PQnfields(res), 1, 4);
|
2014-10-01 17:22:21 +02:00
|
|
|
|
2016-01-05 21:25:12 +01:00
|
|
|
PQclear(res);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (!PQgetisnull(res, 0, 3))
|
|
|
|
*db_name = pg_strdup(PQgetvalue(res, 0, 3));
|
|
|
|
}
|
2014-10-01 17:22:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
Allow pg_receivewal to stream from a slot's restart LSN
Prior to this patch, when running pg_receivewal, the streaming start
point would be the current location of the archives if anything is
found in the local directory where WAL segments are written, and
pg_receivewal would fall back to the current WAL flush location if there
are no archives, as of the result of an IDENTIFY_SYSTEM command.
If for some reason the WAL files from pg_receivewal were moved, it is
better to try a restart where we left at, which is the replication
slot's restart_lsn instead of skipping right to the current flush
location, to avoid holes in the WAL backed up. This commit changes
pg_receivewal to use the following sequence of methods to determine the
starting streaming LSN:
- Scan the local archives.
- Use the slot's restart_lsn, if supported by the backend and if a slot
is defined.
- Fallback to the current flush LSN as reported by IDENTIFY_SYSTEM.
To keep compatibility with older server versions, we only attempt to use
READ_REPLICATION_SLOT if the backend version is at least 15, and
fallback to the older behavior of streaming from the current flush
LSN if the command is not supported.
Some TAP tests are added to cover this feature.
Author: Ronan Dunklau
Reviewed-by: Kyotaro Horiguchi, Michael Paquier, Bharath Rupireddy
Discussion: https://postgr.es/m/18708360.4lzOvYHigE@aivenronan
2021-10-26 02:30:37 +02:00
|
|
|
/*
|
|
|
|
* Run READ_REPLICATION_SLOT through a given connection and give back to
|
|
|
|
* caller some result information if requested for this slot:
|
|
|
|
* - Start LSN position, InvalidXLogRecPtr if unknown.
|
|
|
|
* - Current timeline ID, 0 if unknown.
|
|
|
|
* Returns false on failure, and true otherwise.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
GetSlotInformation(PGconn *conn, const char *slot_name,
|
|
|
|
XLogRecPtr *restart_lsn, TimeLineID *restart_tli)
|
|
|
|
{
|
|
|
|
PGresult *res;
|
|
|
|
PQExpBuffer query;
|
|
|
|
XLogRecPtr lsn_loc = InvalidXLogRecPtr;
|
|
|
|
TimeLineID tli_loc = 0;
|
|
|
|
|
|
|
|
if (restart_lsn)
|
|
|
|
*restart_lsn = lsn_loc;
|
|
|
|
if (restart_tli)
|
|
|
|
*restart_tli = tli_loc;
|
|
|
|
|
|
|
|
query = createPQExpBuffer();
|
|
|
|
appendPQExpBuffer(query, "READ_REPLICATION_SLOT %s", slot_name);
|
|
|
|
res = PQexec(conn, query->data);
|
|
|
|
destroyPQExpBuffer(query);
|
|
|
|
|
|
|
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
|
|
{
|
|
|
|
pg_log_error("could not send replication command \"%s\": %s",
|
|
|
|
"READ_REPLICATION_SLOT", PQerrorMessage(conn));
|
|
|
|
PQclear(res);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The command should always return precisely one tuple and three fields */
|
|
|
|
if (PQntuples(res) != 1 || PQnfields(res) != 3)
|
|
|
|
{
|
|
|
|
pg_log_error("could not read replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields",
|
|
|
|
slot_name, PQntuples(res), PQnfields(res), 1, 3);
|
|
|
|
PQclear(res);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* When the slot doesn't exist, the command returns a tuple with NULL
|
|
|
|
* values. This checks only the slot type field.
|
|
|
|
*/
|
|
|
|
if (PQgetisnull(res, 0, 0))
|
|
|
|
{
|
2022-09-25 00:38:35 +02:00
|
|
|
pg_log_error("replication slot \"%s\" does not exist", slot_name);
|
Allow pg_receivewal to stream from a slot's restart LSN
Prior to this patch, when running pg_receivewal, the streaming start
point would be the current location of the archives if anything is
found in the local directory where WAL segments are written, and
pg_receivewal would fall back to the current WAL flush location if there
are no archives, as of the result of an IDENTIFY_SYSTEM command.
If for some reason the WAL files from pg_receivewal were moved, it is
better to try a restart where we left at, which is the replication
slot's restart_lsn instead of skipping right to the current flush
location, to avoid holes in the WAL backed up. This commit changes
pg_receivewal to use the following sequence of methods to determine the
starting streaming LSN:
- Scan the local archives.
- Use the slot's restart_lsn, if supported by the backend and if a slot
is defined.
- Fallback to the current flush LSN as reported by IDENTIFY_SYSTEM.
To keep compatibility with older server versions, we only attempt to use
READ_REPLICATION_SLOT if the backend version is at least 15, and
fallback to the older behavior of streaming from the current flush
LSN if the command is not supported.
Some TAP tests are added to cover this feature.
Author: Ronan Dunklau
Reviewed-by: Kyotaro Horiguchi, Michael Paquier, Bharath Rupireddy
Discussion: https://postgr.es/m/18708360.4lzOvYHigE@aivenronan
2021-10-26 02:30:37 +02:00
|
|
|
PQclear(res);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Note that this cannot happen as READ_REPLICATION_SLOT supports only
|
|
|
|
* physical slots, but play it safe.
|
|
|
|
*/
|
|
|
|
if (strcmp(PQgetvalue(res, 0, 0), "physical") != 0)
|
|
|
|
{
|
|
|
|
pg_log_error("expected a physical replication slot, got type \"%s\" instead",
|
|
|
|
PQgetvalue(res, 0, 0));
|
|
|
|
PQclear(res);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* restart LSN */
|
|
|
|
if (!PQgetisnull(res, 0, 1))
|
|
|
|
{
|
|
|
|
uint32 hi,
|
|
|
|
lo;
|
|
|
|
|
|
|
|
if (sscanf(PQgetvalue(res, 0, 1), "%X/%X", &hi, &lo) != 2)
|
|
|
|
{
|
|
|
|
pg_log_error("could not parse restart_lsn \"%s\" for replication slot \"%s\"",
|
|
|
|
PQgetvalue(res, 0, 1), slot_name);
|
|
|
|
PQclear(res);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
lsn_loc = ((uint64) hi) << 32 | lo;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* current TLI */
|
|
|
|
if (!PQgetisnull(res, 0, 2))
|
|
|
|
tli_loc = (TimeLineID) atol(PQgetvalue(res, 0, 2));
|
|
|
|
|
|
|
|
PQclear(res);
|
|
|
|
|
|
|
|
/* Assign results if requested */
|
|
|
|
if (restart_lsn)
|
|
|
|
*restart_lsn = lsn_loc;
|
|
|
|
if (restart_tli)
|
|
|
|
*restart_tli = tli_loc;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-10-01 17:22:21 +02:00
|
|
|
/*
|
|
|
|
* Create a replication slot for the given connection. This function
|
2017-03-19 17:06:44 +01:00
|
|
|
* returns true in case of success.
|
2014-10-01 17:22:21 +02:00
|
|
|
*/
|
|
|
|
bool
|
|
|
|
CreateReplicationSlot(PGconn *conn, const char *slot_name, const char *plugin,
|
2017-09-26 22:07:52 +02:00
|
|
|
bool is_temporary, bool is_physical, bool reserve_wal,
|
2021-06-30 05:15:47 +02:00
|
|
|
bool slot_exists_ok, bool two_phase)
|
2014-10-01 17:22:21 +02:00
|
|
|
{
|
|
|
|
PQExpBuffer query;
|
|
|
|
PGresult *res;
|
Flexible options for CREATE_REPLICATION_SLOT.
Like BASE_BACKUP, CREATE_REPLICATION_SLOT has historically used a
hard-coded syntax. To improve future extensibility, adopt a flexible
options syntax here, too.
In the new syntax, instead of three mutually exclusive options
EXPORT_SNAPSHOT, USE_SNAPSHOT, and NOEXPORT_SNAPSHOT, there is now a single
SNAPSHOT option with three possible values: 'export', 'use', and 'nothing'.
This commit does not remove support for the old syntax. It just adds
the new one as an additional option, makes pg_receivewal,
pg_recvlogical, and walreceiver processes use it.
Patch by me, reviewed by Fabien Coelho, Sergei Kornilov, and
Fujii Masao.
Discussion: http://postgr.es/m/CA+TgmobAczXDRO_Gr2euo_TxgzaH1JxbNxvFx=HYvBinefNH8Q@mail.gmail.com
Discussion: http://postgr.es/m/CA+TgmoZGwR=ZVWFeecncubEyPdwghnvfkkdBe9BLccLSiqdf9Q@mail.gmail.com
2021-10-05 18:52:49 +02:00
|
|
|
bool use_new_option_syntax = (PQserverVersion(conn) >= 150000);
|
2014-10-01 17:22:21 +02:00
|
|
|
|
|
|
|
query = createPQExpBuffer();
|
|
|
|
|
|
|
|
Assert((is_physical && plugin == NULL) ||
|
|
|
|
(!is_physical && plugin != NULL));
|
2021-06-30 05:15:47 +02:00
|
|
|
Assert(!(two_phase && is_physical));
|
2014-10-01 17:22:21 +02:00
|
|
|
Assert(slot_name != NULL);
|
|
|
|
|
Flexible options for CREATE_REPLICATION_SLOT.
Like BASE_BACKUP, CREATE_REPLICATION_SLOT has historically used a
hard-coded syntax. To improve future extensibility, adopt a flexible
options syntax here, too.
In the new syntax, instead of three mutually exclusive options
EXPORT_SNAPSHOT, USE_SNAPSHOT, and NOEXPORT_SNAPSHOT, there is now a single
SNAPSHOT option with three possible values: 'export', 'use', and 'nothing'.
This commit does not remove support for the old syntax. It just adds
the new one as an additional option, makes pg_receivewal,
pg_recvlogical, and walreceiver processes use it.
Patch by me, reviewed by Fabien Coelho, Sergei Kornilov, and
Fujii Masao.
Discussion: http://postgr.es/m/CA+TgmobAczXDRO_Gr2euo_TxgzaH1JxbNxvFx=HYvBinefNH8Q@mail.gmail.com
Discussion: http://postgr.es/m/CA+TgmoZGwR=ZVWFeecncubEyPdwghnvfkkdBe9BLccLSiqdf9Q@mail.gmail.com
2021-10-05 18:52:49 +02:00
|
|
|
/* Build base portion of query */
|
2017-09-26 22:07:52 +02:00
|
|
|
appendPQExpBuffer(query, "CREATE_REPLICATION_SLOT \"%s\"", slot_name);
|
|
|
|
if (is_temporary)
|
2019-07-04 03:01:13 +02:00
|
|
|
appendPQExpBufferStr(query, " TEMPORARY");
|
2014-10-01 17:22:21 +02:00
|
|
|
if (is_physical)
|
2019-07-04 03:01:13 +02:00
|
|
|
appendPQExpBufferStr(query, " PHYSICAL");
|
Flexible options for CREATE_REPLICATION_SLOT.
Like BASE_BACKUP, CREATE_REPLICATION_SLOT has historically used a
hard-coded syntax. To improve future extensibility, adopt a flexible
options syntax here, too.
In the new syntax, instead of three mutually exclusive options
EXPORT_SNAPSHOT, USE_SNAPSHOT, and NOEXPORT_SNAPSHOT, there is now a single
SNAPSHOT option with three possible values: 'export', 'use', and 'nothing'.
This commit does not remove support for the old syntax. It just adds
the new one as an additional option, makes pg_receivewal,
pg_recvlogical, and walreceiver processes use it.
Patch by me, reviewed by Fabien Coelho, Sergei Kornilov, and
Fujii Masao.
Discussion: http://postgr.es/m/CA+TgmobAczXDRO_Gr2euo_TxgzaH1JxbNxvFx=HYvBinefNH8Q@mail.gmail.com
Discussion: http://postgr.es/m/CA+TgmoZGwR=ZVWFeecncubEyPdwghnvfkkdBe9BLccLSiqdf9Q@mail.gmail.com
2021-10-05 18:52:49 +02:00
|
|
|
else
|
|
|
|
appendPQExpBuffer(query, " LOGICAL \"%s\"", plugin);
|
|
|
|
|
|
|
|
/* Add any requested options */
|
|
|
|
if (use_new_option_syntax)
|
|
|
|
appendPQExpBufferStr(query, " (");
|
|
|
|
if (is_physical)
|
|
|
|
{
|
2017-09-26 22:07:52 +02:00
|
|
|
if (reserve_wal)
|
Flexible options for CREATE_REPLICATION_SLOT.
Like BASE_BACKUP, CREATE_REPLICATION_SLOT has historically used a
hard-coded syntax. To improve future extensibility, adopt a flexible
options syntax here, too.
In the new syntax, instead of three mutually exclusive options
EXPORT_SNAPSHOT, USE_SNAPSHOT, and NOEXPORT_SNAPSHOT, there is now a single
SNAPSHOT option with three possible values: 'export', 'use', and 'nothing'.
This commit does not remove support for the old syntax. It just adds
the new one as an additional option, makes pg_receivewal,
pg_recvlogical, and walreceiver processes use it.
Patch by me, reviewed by Fabien Coelho, Sergei Kornilov, and
Fujii Masao.
Discussion: http://postgr.es/m/CA+TgmobAczXDRO_Gr2euo_TxgzaH1JxbNxvFx=HYvBinefNH8Q@mail.gmail.com
Discussion: http://postgr.es/m/CA+TgmoZGwR=ZVWFeecncubEyPdwghnvfkkdBe9BLccLSiqdf9Q@mail.gmail.com
2021-10-05 18:52:49 +02:00
|
|
|
AppendPlainCommandOption(query, use_new_option_syntax,
|
|
|
|
"RESERVE_WAL");
|
2017-09-26 22:07:52 +02:00
|
|
|
}
|
2014-10-01 17:22:21 +02:00
|
|
|
else
|
2017-03-14 22:13:56 +01:00
|
|
|
{
|
2021-06-30 05:15:47 +02:00
|
|
|
if (two_phase && PQserverVersion(conn) >= 150000)
|
Flexible options for CREATE_REPLICATION_SLOT.
Like BASE_BACKUP, CREATE_REPLICATION_SLOT has historically used a
hard-coded syntax. To improve future extensibility, adopt a flexible
options syntax here, too.
In the new syntax, instead of three mutually exclusive options
EXPORT_SNAPSHOT, USE_SNAPSHOT, and NOEXPORT_SNAPSHOT, there is now a single
SNAPSHOT option with three possible values: 'export', 'use', and 'nothing'.
This commit does not remove support for the old syntax. It just adds
the new one as an additional option, makes pg_receivewal,
pg_recvlogical, and walreceiver processes use it.
Patch by me, reviewed by Fabien Coelho, Sergei Kornilov, and
Fujii Masao.
Discussion: http://postgr.es/m/CA+TgmobAczXDRO_Gr2euo_TxgzaH1JxbNxvFx=HYvBinefNH8Q@mail.gmail.com
Discussion: http://postgr.es/m/CA+TgmoZGwR=ZVWFeecncubEyPdwghnvfkkdBe9BLccLSiqdf9Q@mail.gmail.com
2021-10-05 18:52:49 +02:00
|
|
|
AppendPlainCommandOption(query, use_new_option_syntax,
|
|
|
|
"TWO_PHASE");
|
2021-06-30 05:15:47 +02:00
|
|
|
|
2017-03-14 22:13:56 +01:00
|
|
|
if (PQserverVersion(conn) >= 100000)
|
Flexible options for CREATE_REPLICATION_SLOT.
Like BASE_BACKUP, CREATE_REPLICATION_SLOT has historically used a
hard-coded syntax. To improve future extensibility, adopt a flexible
options syntax here, too.
In the new syntax, instead of three mutually exclusive options
EXPORT_SNAPSHOT, USE_SNAPSHOT, and NOEXPORT_SNAPSHOT, there is now a single
SNAPSHOT option with three possible values: 'export', 'use', and 'nothing'.
This commit does not remove support for the old syntax. It just adds
the new one as an additional option, makes pg_receivewal,
pg_recvlogical, and walreceiver processes use it.
Patch by me, reviewed by Fabien Coelho, Sergei Kornilov, and
Fujii Masao.
Discussion: http://postgr.es/m/CA+TgmobAczXDRO_Gr2euo_TxgzaH1JxbNxvFx=HYvBinefNH8Q@mail.gmail.com
Discussion: http://postgr.es/m/CA+TgmoZGwR=ZVWFeecncubEyPdwghnvfkkdBe9BLccLSiqdf9Q@mail.gmail.com
2021-10-05 18:52:49 +02:00
|
|
|
{
|
2017-03-14 22:13:56 +01:00
|
|
|
/* pg_recvlogical doesn't use an exported snapshot, so suppress */
|
Flexible options for CREATE_REPLICATION_SLOT.
Like BASE_BACKUP, CREATE_REPLICATION_SLOT has historically used a
hard-coded syntax. To improve future extensibility, adopt a flexible
options syntax here, too.
In the new syntax, instead of three mutually exclusive options
EXPORT_SNAPSHOT, USE_SNAPSHOT, and NOEXPORT_SNAPSHOT, there is now a single
SNAPSHOT option with three possible values: 'export', 'use', and 'nothing'.
This commit does not remove support for the old syntax. It just adds
the new one as an additional option, makes pg_receivewal,
pg_recvlogical, and walreceiver processes use it.
Patch by me, reviewed by Fabien Coelho, Sergei Kornilov, and
Fujii Masao.
Discussion: http://postgr.es/m/CA+TgmobAczXDRO_Gr2euo_TxgzaH1JxbNxvFx=HYvBinefNH8Q@mail.gmail.com
Discussion: http://postgr.es/m/CA+TgmoZGwR=ZVWFeecncubEyPdwghnvfkkdBe9BLccLSiqdf9Q@mail.gmail.com
2021-10-05 18:52:49 +02:00
|
|
|
if (use_new_option_syntax)
|
|
|
|
AppendStringCommandOption(query, use_new_option_syntax,
|
|
|
|
"SNAPSHOT", "nothing");
|
|
|
|
else
|
|
|
|
AppendPlainCommandOption(query, use_new_option_syntax,
|
|
|
|
"NOEXPORT_SNAPSHOT");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (use_new_option_syntax)
|
|
|
|
{
|
|
|
|
/* Suppress option list if it would be empty, otherwise terminate */
|
|
|
|
if (query->data[query->len - 1] == '(')
|
|
|
|
{
|
|
|
|
query->len -= 2;
|
|
|
|
query->data[query->len] = '\0';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
appendPQExpBufferChar(query, ')');
|
2017-03-14 22:13:56 +01:00
|
|
|
}
|
2014-10-01 17:22:21 +02:00
|
|
|
|
Flexible options for CREATE_REPLICATION_SLOT.
Like BASE_BACKUP, CREATE_REPLICATION_SLOT has historically used a
hard-coded syntax. To improve future extensibility, adopt a flexible
options syntax here, too.
In the new syntax, instead of three mutually exclusive options
EXPORT_SNAPSHOT, USE_SNAPSHOT, and NOEXPORT_SNAPSHOT, there is now a single
SNAPSHOT option with three possible values: 'export', 'use', and 'nothing'.
This commit does not remove support for the old syntax. It just adds
the new one as an additional option, makes pg_receivewal,
pg_recvlogical, and walreceiver processes use it.
Patch by me, reviewed by Fabien Coelho, Sergei Kornilov, and
Fujii Masao.
Discussion: http://postgr.es/m/CA+TgmobAczXDRO_Gr2euo_TxgzaH1JxbNxvFx=HYvBinefNH8Q@mail.gmail.com
Discussion: http://postgr.es/m/CA+TgmoZGwR=ZVWFeecncubEyPdwghnvfkkdBe9BLccLSiqdf9Q@mail.gmail.com
2021-10-05 18:52:49 +02:00
|
|
|
/* Now run the query */
|
2014-10-01 17:22:21 +02:00
|
|
|
res = PQexec(conn, query->data);
|
|
|
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
|
|
|
{
|
2015-07-12 22:06:27 +02:00
|
|
|
const char *sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
|
2014-10-06 17:18:13 +02:00
|
|
|
|
2015-08-12 17:35:50 +02:00
|
|
|
if (slot_exists_ok &&
|
|
|
|
sqlstate &&
|
|
|
|
strcmp(sqlstate, ERRCODE_DUPLICATE_OBJECT) == 0)
|
2015-07-12 22:06:27 +02:00
|
|
|
{
|
|
|
|
destroyPQExpBuffer(query);
|
|
|
|
PQclear(res);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not send replication command \"%s\": %s",
|
|
|
|
query->data, PQerrorMessage(conn));
|
2015-07-12 22:06:27 +02:00
|
|
|
|
|
|
|
destroyPQExpBuffer(query);
|
|
|
|
PQclear(res);
|
|
|
|
return false;
|
|
|
|
}
|
2014-10-01 17:22:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (PQntuples(res) != 1 || PQnfields(res) != 4)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields",
|
|
|
|
slot_name,
|
|
|
|
PQntuples(res), PQnfields(res), 1, 4);
|
2014-10-06 17:18:13 +02:00
|
|
|
|
|
|
|
destroyPQExpBuffer(query);
|
|
|
|
PQclear(res);
|
2014-10-01 17:22:21 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-10-06 17:18:13 +02:00
|
|
|
destroyPQExpBuffer(query);
|
2014-10-01 17:22:21 +02:00
|
|
|
PQclear(res);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Drop a replication slot for the given connection. This function
|
|
|
|
* returns true in case of success.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
DropReplicationSlot(PGconn *conn, const char *slot_name)
|
|
|
|
{
|
|
|
|
PQExpBuffer query;
|
|
|
|
PGresult *res;
|
|
|
|
|
|
|
|
Assert(slot_name != NULL);
|
|
|
|
|
|
|
|
query = createPQExpBuffer();
|
|
|
|
|
|
|
|
/* Build query */
|
|
|
|
appendPQExpBuffer(query, "DROP_REPLICATION_SLOT \"%s\"",
|
|
|
|
slot_name);
|
|
|
|
res = PQexec(conn, query->data);
|
|
|
|
if (PQresultStatus(res) != PGRES_COMMAND_OK)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not send replication command \"%s\": %s",
|
|
|
|
query->data, PQerrorMessage(conn));
|
2014-10-06 17:18:13 +02:00
|
|
|
|
|
|
|
destroyPQExpBuffer(query);
|
|
|
|
PQclear(res);
|
2014-10-01 17:22:21 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PQntuples(res) != 0 || PQnfields(res) != 0)
|
|
|
|
{
|
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
|
|
|
pg_log_error("could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields",
|
|
|
|
slot_name,
|
|
|
|
PQntuples(res), PQnfields(res), 0, 0);
|
2014-10-06 17:18:13 +02:00
|
|
|
|
|
|
|
destroyPQExpBuffer(query);
|
|
|
|
PQclear(res);
|
2014-10-01 17:22:21 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-07-12 22:25:51 +02:00
|
|
|
destroyPQExpBuffer(query);
|
2014-10-01 17:22:21 +02:00
|
|
|
PQclear(res);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
Flexible options for BASE_BACKUP.
Previously, BASE_BACKUP used an entirely hard-coded syntax, but that's
hard to extend. Instead, adopt the same kind of syntax we've used for
SQL commands such as VACUUM, ANALYZE, COPY, and EXPLAIN, where it's
not necessary for all of the option names to be parser keywords.
In the new syntax, most of the options now take an optional Boolean
argument. To match our practice in other in places, the options which
the old syntax called NOWAIT and NOVERIFY_CHECKSUMS options are in the
new syntax called WAIT and VERIFY_CHECKUMS, and the default value is
false. In the new syntax, the FAST option has been replaced by a
CHECKSUM option whose value may be 'fast' or 'spread'.
This commit does not remove support for the old syntax. It just adds
the new one as an additional option, and makes pg_basebackup prefer
the new syntax when the server is new enough to support it.
Patch by me, reviewed and tested by Fabien Coelho, Sergei Kornilov,
Fujii Masao, and Tushar Ahuja.
Discussion: http://postgr.es/m/CA+TgmobAczXDRO_Gr2euo_TxgzaH1JxbNxvFx=HYvBinefNH8Q@mail.gmail.com
Discussion: http://postgr.es/m/CA+TgmoZGwR=ZVWFeecncubEyPdwghnvfkkdBe9BLccLSiqdf9Q@mail.gmail.com
2021-10-05 17:50:21 +02:00
|
|
|
/*
|
|
|
|
* Append a "plain" option - one with no value - to a server command that
|
|
|
|
* is being constructed.
|
|
|
|
*
|
|
|
|
* In the old syntax, all options were parser keywords, so you could just
|
|
|
|
* write things like SOME_COMMAND OPTION1 OPTION2 'opt2value' OPTION3 42. The
|
|
|
|
* new syntax uses a comma-separated list surrounded by parentheses, so the
|
|
|
|
* equivalent is SOME_COMMAND (OPTION1, OPTION2 'optvalue', OPTION3 42).
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
AppendPlainCommandOption(PQExpBuffer buf, bool use_new_option_syntax,
|
|
|
|
char *option_name)
|
|
|
|
{
|
|
|
|
if (buf->len > 0 && buf->data[buf->len - 1] != '(')
|
|
|
|
{
|
|
|
|
if (use_new_option_syntax)
|
|
|
|
appendPQExpBufferStr(buf, ", ");
|
|
|
|
else
|
|
|
|
appendPQExpBufferChar(buf, ' ');
|
|
|
|
}
|
|
|
|
|
|
|
|
appendPQExpBuffer(buf, " %s", option_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Append an option with an associated string value to a server command that
|
|
|
|
* is being constructed.
|
|
|
|
*
|
|
|
|
* See comments for AppendPlainCommandOption, above.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
AppendStringCommandOption(PQExpBuffer buf, bool use_new_option_syntax,
|
|
|
|
char *option_name, char *option_value)
|
|
|
|
{
|
|
|
|
AppendPlainCommandOption(buf, use_new_option_syntax, option_name);
|
|
|
|
|
|
|
|
if (option_value != NULL)
|
|
|
|
{
|
|
|
|
size_t length = strlen(option_value);
|
|
|
|
char *escaped_value = palloc(1 + 2 * length);
|
|
|
|
|
|
|
|
PQescapeStringConn(conn, escaped_value, option_value, length, NULL);
|
|
|
|
appendPQExpBuffer(buf, " '%s'", escaped_value);
|
|
|
|
pfree(escaped_value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Append an option with an associated integer value to a server command
|
|
|
|
* is being constructed.
|
|
|
|
*
|
|
|
|
* See comments for AppendPlainCommandOption, above.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
AppendIntegerCommandOption(PQExpBuffer buf, bool use_new_option_syntax,
|
|
|
|
char *option_name, int32 option_value)
|
|
|
|
{
|
|
|
|
AppendPlainCommandOption(buf, use_new_option_syntax, option_name);
|
|
|
|
|
|
|
|
appendPQExpBuffer(buf, " %d", option_value);
|
|
|
|
}
|
2014-03-18 17:19:57 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Frontend version of GetCurrentTimestamp(), since we are not linked with
|
2017-02-23 21:57:08 +01:00
|
|
|
* backend code.
|
2014-03-18 17:19:57 +01:00
|
|
|
*/
|
2017-02-23 21:57:08 +01:00
|
|
|
TimestampTz
|
2014-03-18 17:19:57 +01:00
|
|
|
feGetCurrentTimestamp(void)
|
|
|
|
{
|
2017-02-23 21:57:08 +01:00
|
|
|
TimestampTz result;
|
2014-03-18 17:19:57 +01:00
|
|
|
struct timeval tp;
|
|
|
|
|
|
|
|
gettimeofday(&tp, NULL);
|
|
|
|
|
2017-02-23 21:57:08 +01:00
|
|
|
result = (TimestampTz) tp.tv_sec -
|
2014-03-18 17:19:57 +01:00
|
|
|
((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);
|
|
|
|
result = (result * USECS_PER_SEC) + tp.tv_usec;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Frontend version of TimestampDifference(), since we are not linked with
|
|
|
|
* backend code.
|
|
|
|
*/
|
|
|
|
void
|
2017-02-23 21:57:08 +01:00
|
|
|
feTimestampDifference(TimestampTz start_time, TimestampTz stop_time,
|
2014-03-18 17:19:57 +01:00
|
|
|
long *secs, int *microsecs)
|
|
|
|
{
|
2017-02-23 21:57:08 +01:00
|
|
|
TimestampTz diff = stop_time - start_time;
|
2014-03-18 17:19:57 +01:00
|
|
|
|
|
|
|
if (diff <= 0)
|
|
|
|
{
|
|
|
|
*secs = 0;
|
|
|
|
*microsecs = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*secs = (long) (diff / USECS_PER_SEC);
|
|
|
|
*microsecs = (int) (diff % USECS_PER_SEC);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Frontend version of TimestampDifferenceExceeds(), since we are not
|
|
|
|
* linked with backend code.
|
|
|
|
*/
|
|
|
|
bool
|
2017-02-23 21:57:08 +01:00
|
|
|
feTimestampDifferenceExceeds(TimestampTz start_time,
|
|
|
|
TimestampTz stop_time,
|
2014-03-18 17:19:57 +01:00
|
|
|
int msec)
|
|
|
|
{
|
2017-02-23 21:57:08 +01:00
|
|
|
TimestampTz diff = stop_time - start_time;
|
2014-03-18 17:19:57 +01:00
|
|
|
|
|
|
|
return (diff >= msec * INT64CONST(1000));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Converts an int64 to network byte order.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
fe_sendint64(int64 i, char *buf)
|
|
|
|
{
|
2017-10-02 00:36:14 +02:00
|
|
|
uint64 n64 = pg_hton64(i);
|
2014-03-18 17:19:57 +01:00
|
|
|
|
2017-10-02 00:36:14 +02:00
|
|
|
memcpy(buf, &n64, sizeof(n64));
|
2014-03-18 17:19:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Converts an int64 from network byte order to native format.
|
|
|
|
*/
|
|
|
|
int64
|
|
|
|
fe_recvint64(char *buf)
|
|
|
|
{
|
2017-10-02 00:36:14 +02:00
|
|
|
uint64 n64;
|
2014-03-18 17:19:57 +01:00
|
|
|
|
2017-10-02 00:36:14 +02:00
|
|
|
memcpy(&n64, buf, sizeof(n64));
|
2014-03-18 17:19:57 +01:00
|
|
|
|
2017-10-02 00:36:14 +02:00
|
|
|
return pg_ntoh64(n64);
|
2014-03-18 17:19:57 +01:00
|
|
|
}
|