PATCH: pgagent connection string parsing

From: Thomas Krennwallner <tk+pgsql(at)postsubmeta(dot)net>
To: pgadmin-hackers(at)postgresql(dot)org
Subject: PATCH: pgagent connection string parsing
Date: 2017-08-20 17:17:52
Message-ID: 20170820171752.GB23580@postsubmeta.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgadmin-hackers

Hi!

I tried to pass the libpq parameter connect_timeout on the pgagent
command-line without success:

% ./pgagent -f -t60 -l2 dbname=xxx user=tkren connect_timeout=5
Sun Aug 20 18:24:26 2017 : DEBUG: Creating primary connection
Sun Aug 20 18:24:26 2017 : ERROR: Primary connection string is not valid!

connInfo::getConnectionString() misspelled this parameter as
connection_timeout, which subsequently breaks the PQconnectdb() call
in DBconn::Connect():

% ./pgagent -f -t60 -l2 dbname=xxx user=tkren connection_timeout=5
Sun Aug 20 18:24:34 2017 : DEBUG: Creating primary connection
Sun Aug 20 18:24:34 2017 : DEBUG: Connection Information:
Sun Aug 20 18:24:34 2017 : DEBUG: user : tkren
Sun Aug 20 18:24:34 2017 : DEBUG: port : 0
Sun Aug 20 18:24:34 2017 : DEBUG: host :
Sun Aug 20 18:24:34 2017 : DEBUG: dbname : xxx
Sun Aug 20 18:24:34 2017 : DEBUG: password :
Sun Aug 20 18:24:34 2017 : DEBUG: conn timeout : 5
Sun Aug 20 18:24:34 2017 : DEBUG: Connection Information:
Sun Aug 20 18:24:34 2017 : DEBUG: user : tkren
Sun Aug 20 18:24:34 2017 : DEBUG: port : 0
Sun Aug 20 18:24:34 2017 : DEBUG: host :
Sun Aug 20 18:24:34 2017 : DEBUG: dbname : xxx
Sun Aug 20 18:24:34 2017 : DEBUG: password :
Sun Aug 20 18:24:34 2017 : DEBUG: conn timeout : 5
Sun Aug 20 18:24:34 2017 : DEBUG: Creating DB connection: user=tkren connection_timeout=5 dbname=xxx
Sun Aug 20 18:24:34 2017 : WARNING: Couldn't create the primary connection (attempt 1): invalid connection option "connection_timeout"
Sun Aug 20 18:24:34 2017 : DEBUG: Clearing all connections
Sun Aug 20 18:24:34 2017 : DEBUG: Connection stats: total - 1, free - 0, deleted - 1

During my code inspection, I realized that pgagent does not support
application_name and other parameters from libpq:

% ./pgagent -f -t60 -l2 dbname=xxx user=tkren application_name=abc
Sun Aug 20 18:31:19 2017 : DEBUG: Creating primary connection
Sun Aug 20 18:31:19 2017 : ERROR: Primary connection string is not valid!

See also this thread on pgadmin-support:
https://www.postgresql.org/message-id/559AC825.6010708%40agliodbs.com

Using PGAPPNAME would be an option, but we use pgagent on Windows as
well, and this makes it unnecessarily hard to set environment
variables for services. It would be also be nice to have support for
application_name on the jobstep level, but PGAPPNAME can only be set
globally.

To fix this issue, I've refactored connInfo and DBconn and use of
PQconninfoParse() for connection string parsing. With the attached
patch applied, pgagent supports both vanilla keyword/value connection
strings and postgresql:// URIs as command-line options as well as
stored in the jstconnstr column of pgagent.pga_jobstep. We now
support all parameter keywords from libpq, and fix the aforementioned
misspelled connect_timeout parameter.

In a patched pgagent, we can now do the following. With the jobsteps
shown below that are part of a job running every minute,

xxx=# select * from pgagent.pga_jobstep;
jstid | jstjobid | jstname | jstdesc | jstenabled | jstkind | jstcode | jstconnstr | jstdbname | jstonerror | jscnextrun
-------+----------+-------------------------+---------+------------+---------+---------------------+------------------------------------------------+-----------+------------+------------
2 | 1 | pg_sleep(10) local | | t | s | select pg_sleep(10) | | xxx | f |
3 | 1 | pg_sleep(10) remote uri | | t | s | select pg_sleep(10) | postgresql://tkren(at)localhost:5432/xxx | | f |
1 | 1 | pg_sleep(10) remote | | t | s | select pg_sleep(10) | user=tkren host=localhost port=5432 dbname=xxx | | f |
(3 rows)

we can run pgagent and get the following trace. Note that connection
pooling works as intended with postgresql:// URIs and keyword/value
connection strings.

% ./pgagent -f -t60 -l2 dbname=xxx user=tkren application_name=xyz
Sun Aug 20 19:03:01 2017 : DEBUG: Creating primary connection
Sun Aug 20 19:03:01 2017 : DEBUG: Parsing connection information: dbname=xxx user=tkren application_name=xyz
Sun Aug 20 19:03:01 2017 : DEBUG: Database-User: tkren
Sun Aug 20 19:03:01 2017 : DEBUG: Database-Name: xxx
Sun Aug 20 19:03:01 2017 : DEBUG: Application-Name: xyz
Sun Aug 20 19:03:01 2017 : DEBUG: Creating DB connection: 'user=tkren dbname=xxx application_name=xyz'
Sun Aug 20 19:03:01 2017 : DEBUG: Database sanity check
Sun Aug 20 19:03:01 2017 : DEBUG: Clearing zombies
Sun Aug 20 19:03:01 2017 : DEBUG: Checking for jobs to run
Sun Aug 20 19:03:01 2017 : DEBUG: Creating job thread for job 1
Sun Aug 20 19:03:01 2017 : DEBUG: Creating DB connection: 'user=tkren dbname=xxx application_name=xyz'
Sun Aug 20 19:03:01 2017 : DEBUG: Allocating new connection 'user=tkren dbname=xxx application_name=xyz' to database xxx
Sun Aug 20 19:03:01 2017 : DEBUG: Starting job: 1
Sun Aug 20 19:03:01 2017 : DEBUG: Sleeping...
Sun Aug 20 19:03:01 2017 : DEBUG: Parsing connection information: user=tkren dbname=xxx application_name=xyz dbname=xxx
Sun Aug 20 19:03:01 2017 : DEBUG: Database-User: tkren
Sun Aug 20 19:03:01 2017 : DEBUG: Database-Name: xxx
Sun Aug 20 19:03:01 2017 : DEBUG: Application-Name: xyz
Sun Aug 20 19:03:01 2017 : DEBUG: Creating DB connection: 'user=tkren dbname=xxx application_name=xyz'
Sun Aug 20 19:03:01 2017 : DEBUG: Allocating new connection 'user=tkren dbname=xxx application_name=xyz' to database xxx
Sun Aug 20 19:03:01 2017 : DEBUG: Executing SQL step 2 (part of job 1)
Sun Aug 20 19:03:11 2017 : DEBUG: Returning connection 'user=tkren dbname=xxx application_name=xyz' to database xxx
Sun Aug 20 19:03:11 2017 : DEBUG: Parsing connection information: user=tkren host=localhost port=5432 dbname=xxx
Sun Aug 20 19:03:11 2017 : DEBUG: Database-User: tkren
Sun Aug 20 19:03:11 2017 : DEBUG: Database-Name: xxx
Sun Aug 20 19:03:11 2017 : DEBUG: Database-Host: localhost
Sun Aug 20 19:03:11 2017 : DEBUG: Database-Port: 5432
Sun Aug 20 19:03:11 2017 : DEBUG: Creating DB connection: 'user=tkren dbname=xxx host=localhost port=5432'
Sun Aug 20 19:03:11 2017 : DEBUG: Allocating new connection 'user=tkren dbname=xxx host=localhost port=5432' to database xxx
Sun Aug 20 19:03:11 2017 : DEBUG: Executing SQL step 1 (part of job 1)
Sun Aug 20 19:03:21 2017 : DEBUG: Returning connection 'user=tkren dbname=xxx host=localhost port=5432' to database xxx
Sun Aug 20 19:03:21 2017 : DEBUG: Parsing connection information: postgresql://tkren(at)localhost:5432/xxx
Sun Aug 20 19:03:21 2017 : DEBUG: Database-User: tkren
Sun Aug 20 19:03:21 2017 : DEBUG: Database-Name: xxx
Sun Aug 20 19:03:21 2017 : DEBUG: Database-Host: localhost
Sun Aug 20 19:03:21 2017 : DEBUG: Database-Port: 5432
Sun Aug 20 19:03:21 2017 : DEBUG: Allocating existing connection 'user=tkren dbname=xxx host=localhost port=5432' to database xxx
Sun Aug 20 19:03:21 2017 : DEBUG: Executing SQL step 3 (part of job 1)
Sun Aug 20 19:03:31 2017 : DEBUG: Returning connection 'user=tkren dbname=xxx host=localhost port=5432' to database xxx
Sun Aug 20 19:03:32 2017 : DEBUG: Returning connection 'user=tkren dbname=xxx application_name=xyz' to database xxx
Sun Aug 20 19:03:32 2017 : DEBUG: Completed job: 1
Sun Aug 20 19:03:32 2017 : DEBUG: Destroying job thread for job 1
Sun Aug 20 19:04:01 2017 : DEBUG: Checking for jobs to run
Sun Aug 20 19:04:01 2017 : DEBUG: Creating job thread for job 1
Sun Aug 20 19:04:01 2017 : DEBUG: Allocating existing connection 'user=tkren dbname=xxx application_name=xyz' to database xxx
Sun Aug 20 19:04:01 2017 : DEBUG: Starting job: 1
Sun Aug 20 19:04:01 2017 : DEBUG: Sleeping...
Sun Aug 20 19:04:01 2017 : DEBUG: Allocating existing connection 'user=tkren dbname=xxx application_name=xyz' to database xxx
Sun Aug 20 19:04:01 2017 : DEBUG: Executing SQL step 2 (part of job 1)
Sun Aug 20 19:04:11 2017 : DEBUG: Returning connection 'user=tkren dbname=xxx application_name=xyz' to database xxx
Sun Aug 20 19:04:11 2017 : DEBUG: Parsing connection information: user=tkren host=localhost port=5432 dbname=xxx
Sun Aug 20 19:04:11 2017 : DEBUG: Database-User: tkren
Sun Aug 20 19:04:11 2017 : DEBUG: Database-Name: xxx
Sun Aug 20 19:04:11 2017 : DEBUG: Database-Host: localhost
Sun Aug 20 19:04:11 2017 : DEBUG: Database-Port: 5432
Sun Aug 20 19:04:11 2017 : DEBUG: Allocating existing connection 'user=tkren dbname=xxx host=localhost port=5432' to database xxx
Sun Aug 20 19:04:11 2017 : DEBUG: Executing SQL step 1 (part of job 1)
Sun Aug 20 19:04:21 2017 : DEBUG: Returning connection 'user=tkren dbname=xxx host=localhost port=5432' to database xxx
Sun Aug 20 19:04:21 2017 : DEBUG: Parsing connection information: postgresql://tkren(at)localhost:5432/xxx
Sun Aug 20 19:04:21 2017 : DEBUG: Database-User: tkren
Sun Aug 20 19:04:21 2017 : DEBUG: Database-Name: xxx
Sun Aug 20 19:04:21 2017 : DEBUG: Database-Host: localhost
Sun Aug 20 19:04:21 2017 : DEBUG: Database-Port: 5432
Sun Aug 20 19:04:21 2017 : DEBUG: Allocating existing connection 'user=tkren dbname=xxx host=localhost port=5432' to database xxx
Sun Aug 20 19:04:21 2017 : DEBUG: Executing SQL step 3 (part of job 1)
Sun Aug 20 19:04:31 2017 : DEBUG: Returning connection 'user=tkren dbname=xxx host=localhost port=5432' to database xxx
Sun Aug 20 19:04:32 2017 : DEBUG: Returning connection 'user=tkren dbname=xxx application_name=xyz' to database xxx
Sun Aug 20 19:04:32 2017 : DEBUG: Completed job: 1
Sun Aug 20 19:04:32 2017 : DEBUG: Destroying job thread for job 1
[...]

TK

Attachment Content-Type Size
0001-connection-info-refactoring.patch text/x-diff 15.8 KB

Responses

Browse pgadmin-hackers by date

  From Date Subject
Next Message Ashesh Vashi 2017-08-21 01:20:03 Re: PATCH: pgagent connection string parsing
Previous Message Dave Cramer 2017-08-18 12:37:09 Re: [pgadmin4][Patch] Greenplum specific DDL and Dashboard display