mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-17 19:13:16 +08:00
Add error detail when adding a data node fails
When `add_data_node` fails, it often gives an opaque error that it couldn't connect to the data node. This change adds the libpq connection error as a detailed message in the error.
This commit is contained in:
parent
15e1edb76f
commit
eede24bcf2
@ -552,16 +552,27 @@ connect_for_bootstrapping(const char *node_name, const char *const host, int32 p
|
|||||||
const char *username, const char *password)
|
const char *username, const char *password)
|
||||||
{
|
{
|
||||||
TSConnection *conn = NULL;
|
TSConnection *conn = NULL;
|
||||||
|
char *err = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < lengthof(bootstrap_databases); i++)
|
for (i = 0; i < lengthof(bootstrap_databases); i++)
|
||||||
{
|
{
|
||||||
List *node_options =
|
List *node_options =
|
||||||
create_data_node_options(host, port, bootstrap_databases[i], username, password);
|
create_data_node_options(host, port, bootstrap_databases[i], username, password);
|
||||||
conn = remote_connection_open_with_options_nothrow(node_name, node_options);
|
conn = remote_connection_open_with_options_nothrow(node_name, node_options, &err);
|
||||||
|
|
||||||
if (conn)
|
if (conn)
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
return conn;
|
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
|
||||||
|
errmsg("could not connect to \"%s\"", node_name),
|
||||||
|
err == NULL ? 0 : errdetail("%s", err)));
|
||||||
|
|
||||||
|
pg_unreachable();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -726,12 +737,7 @@ data_node_add_internal(PG_FUNCTION_ARGS, bool set_distid)
|
|||||||
{
|
{
|
||||||
TSConnection *conn =
|
TSConnection *conn =
|
||||||
connect_for_bootstrapping(node_name, host, port, username, password);
|
connect_for_bootstrapping(node_name, host, port, username, password);
|
||||||
|
Assert(NULL != conn);
|
||||||
if (NULL == conn)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
|
|
||||||
errmsg("could not connect to \"%s\"", node_name)));
|
|
||||||
|
|
||||||
data_node_validate_extension_availability(conn);
|
data_node_validate_extension_availability(conn);
|
||||||
database_created = data_node_bootstrap_database(conn, &database);
|
database_created = data_node_bootstrap_database(conn, &database);
|
||||||
remote_connection_close(conn);
|
remote_connection_close(conn);
|
||||||
|
@ -1132,6 +1132,23 @@ set_ssl_options(const char *user_name, const char **keywords, const char **value
|
|||||||
*option_start = option_pos;
|
*option_start = option_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Finish the connection and, optionally, save the connection error.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
finish_connection(PGconn *conn, char **errmsg)
|
||||||
|
{
|
||||||
|
if (NULL != errmsg)
|
||||||
|
{
|
||||||
|
if (NULL == conn)
|
||||||
|
*errmsg = "invalid connection";
|
||||||
|
else
|
||||||
|
*errmsg = pchomp(PQerrorMessage(conn));
|
||||||
|
}
|
||||||
|
|
||||||
|
PQfinish(conn);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This will only open a connection to a specific node, but not do anything
|
* This will only open a connection to a specific node, but not do anything
|
||||||
* else. In particular, it will not perform any validation nor configure the
|
* else. In particular, it will not perform any validation nor configure the
|
||||||
@ -1140,7 +1157,8 @@ set_ssl_options(const char *user_name, const char **keywords, const char **value
|
|||||||
* function.
|
* function.
|
||||||
*/
|
*/
|
||||||
TSConnection *
|
TSConnection *
|
||||||
remote_connection_open_with_options_nothrow(const char *node_name, List *connection_options)
|
remote_connection_open_with_options_nothrow(const char *node_name, List *connection_options,
|
||||||
|
char **errmsg)
|
||||||
{
|
{
|
||||||
PGconn *volatile pg_conn = NULL;
|
PGconn *volatile pg_conn = NULL;
|
||||||
const char *user_name = NULL;
|
const char *user_name = NULL;
|
||||||
@ -1150,6 +1168,9 @@ remote_connection_open_with_options_nothrow(const char *node_name, List *connect
|
|||||||
int option_count;
|
int option_count;
|
||||||
int option_pos;
|
int option_pos;
|
||||||
|
|
||||||
|
if (NULL != errmsg)
|
||||||
|
*errmsg = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Construct connection params from generic options of ForeignServer
|
* Construct connection params from generic options of ForeignServer
|
||||||
* and user. (Some of them might not be libpq options, in
|
* and user. (Some of them might not be libpq options, in
|
||||||
@ -1204,7 +1225,7 @@ remote_connection_open_with_options_nothrow(const char *node_name, List *connect
|
|||||||
|
|
||||||
if (PQstatus(pg_conn) == CONNECTION_BAD)
|
if (PQstatus(pg_conn) == CONNECTION_BAD)
|
||||||
{
|
{
|
||||||
PQfinish(pg_conn);
|
finish_connection(pg_conn, errmsg);
|
||||||
pg_conn = NULL;
|
pg_conn = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1221,7 +1242,7 @@ remote_connection_open_with_options_nothrow(const char *node_name, List *connect
|
|||||||
case PGRES_POLLING_FAILED:
|
case PGRES_POLLING_FAILED:
|
||||||
/* connection attempt failed */
|
/* connection attempt failed */
|
||||||
stop_waiting = true;
|
stop_waiting = true;
|
||||||
PQfinish(pg_conn);
|
finish_connection(pg_conn, errmsg);
|
||||||
pg_conn = NULL;
|
pg_conn = NULL;
|
||||||
break;
|
break;
|
||||||
case PGRES_POLLING_OK:
|
case PGRES_POLLING_OK:
|
||||||
@ -1256,7 +1277,7 @@ remote_connection_open_with_options_nothrow(const char *node_name, List *connect
|
|||||||
PG_CATCH();
|
PG_CATCH();
|
||||||
{
|
{
|
||||||
if (NULL != pg_conn)
|
if (NULL != pg_conn)
|
||||||
PQfinish(pg_conn);
|
finish_connection(pg_conn, errmsg);
|
||||||
|
|
||||||
PG_RE_THROW();
|
PG_RE_THROW();
|
||||||
}
|
}
|
||||||
@ -1271,14 +1292,14 @@ remote_connection_open_with_options_nothrow(const char *node_name, List *connect
|
|||||||
|
|
||||||
if (PQstatus(pg_conn) != CONNECTION_OK)
|
if (PQstatus(pg_conn) != CONNECTION_OK)
|
||||||
{
|
{
|
||||||
PQfinish(pg_conn);
|
finish_connection(pg_conn, errmsg);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ts_conn = remote_connection_create(pg_conn, false, node_name);
|
ts_conn = remote_connection_create(pg_conn, false, node_name);
|
||||||
|
|
||||||
if (NULL == ts_conn)
|
if (NULL == ts_conn)
|
||||||
PQfinish(pg_conn);
|
finish_connection(pg_conn, errmsg);
|
||||||
|
|
||||||
return ts_conn;
|
return ts_conn;
|
||||||
}
|
}
|
||||||
@ -1297,12 +1318,15 @@ TSConnection *
|
|||||||
remote_connection_open_with_options(const char *node_name, List *connection_options,
|
remote_connection_open_with_options(const char *node_name, List *connection_options,
|
||||||
bool set_dist_id)
|
bool set_dist_id)
|
||||||
{
|
{
|
||||||
TSConnection *conn = remote_connection_open_with_options_nothrow(node_name, connection_options);
|
char *err = NULL;
|
||||||
|
TSConnection *conn =
|
||||||
|
remote_connection_open_with_options_nothrow(node_name, connection_options, &err);
|
||||||
|
|
||||||
if (NULL == conn)
|
if (NULL == conn)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
|
(errcode(ERRCODE_SQLCLIENT_UNABLE_TO_ESTABLISH_SQLCONNECTION),
|
||||||
errmsg("could not connect to \"%s\"", node_name)));
|
errmsg("could not connect to \"%s\"", node_name),
|
||||||
|
err == NULL ? 0 : errdetail_internal("%s", err)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use PG_TRY block to ensure closing connection on error.
|
* Use PG_TRY block to ensure closing connection on error.
|
||||||
@ -1477,11 +1501,12 @@ remote_connection_open_nothrow(Oid server_id, Oid user_id, char **errmsg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
connection_options = add_userinfo_to_server_options(server, user_id);
|
connection_options = add_userinfo_to_server_options(server, user_id);
|
||||||
conn = remote_connection_open_with_options_nothrow(server->servername, connection_options);
|
conn =
|
||||||
|
remote_connection_open_with_options_nothrow(server->servername, connection_options, errmsg);
|
||||||
|
|
||||||
if (NULL == conn)
|
if (NULL == conn)
|
||||||
{
|
{
|
||||||
if (NULL != errmsg)
|
if (NULL != errmsg && NULL == *errmsg)
|
||||||
*errmsg = "internal connection error";
|
*errmsg = "internal connection error";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,8 @@ extern TSConnection *remote_connection_open_with_options(const char *node_name,
|
|||||||
List *connection_options,
|
List *connection_options,
|
||||||
bool set_dist_id);
|
bool set_dist_id);
|
||||||
extern TSConnection *remote_connection_open_with_options_nothrow(const char *node_name,
|
extern TSConnection *remote_connection_open_with_options_nothrow(const char *node_name,
|
||||||
List *connection_options);
|
List *connection_options,
|
||||||
|
char **errmsg);
|
||||||
extern TSConnection *remote_connection_open_by_id(TSConnectionId id);
|
extern TSConnection *remote_connection_open_by_id(TSConnectionId id);
|
||||||
extern TSConnection *remote_connection_open(Oid server_id, Oid user_id);
|
extern TSConnection *remote_connection_open(Oid server_id, Oid user_id);
|
||||||
extern TSConnection *remote_connection_open_nothrow(Oid server_id, Oid user_id, char **errmsg);
|
extern TSConnection *remote_connection_open_nothrow(Oid server_id, Oid user_id, char **errmsg);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user