1
0
mirror of https://github.com/postgres/postgres.git synced 2025-10-25 13:17:41 +03:00

Support connection load balancing in libpq

This adds support for load balancing connections with libpq using a
connection parameter: load_balance_hosts=<string>. When setting the
param to random, hosts and addresses will be connected to in random
order. This then results in load balancing across these addresses and
hosts when multiple clients or frequent connection setups are used.

The randomization employed performs two levels of shuffling:

  1. The given hosts are randomly shuffled, before resolving them
     one-by-one.
  2. Once a host its addresses get resolved, the returned addresses
     are shuffled, before trying to connect to them one-by-one.

Author: Jelte Fennema <postgres@jeltef.nl>
Reviewed-by: Aleksander Alekseev <aleksander@timescale.com>
Reviewed-by: Michael Banck <mbanck@gmx.net>
Reviewed-by: Andrey Borodin <amborodin86@gmail.com>
Discussion: https://postgr.es/m/PR3PR83MB04768E2FF04818EEB2179949F7A69@PR3PR83MB0476.EURPRD83.prod.outlook.
This commit is contained in:
Daniel Gustafsson
2023-03-29 21:53:38 +02:00
parent 44d85ba5a3
commit 7f5b19817e
10 changed files with 431 additions and 3 deletions

View File

@@ -26,7 +26,8 @@
#include <netdb.h>
#include <sys/socket.h>
#include <time.h>
#ifndef WIN32
/* MinGW has sys/time.h, but MSVC doesn't */
#ifndef _MSC_VER
#include <sys/time.h>
#endif
@@ -82,6 +83,8 @@ typedef struct
#endif
#endif /* USE_OPENSSL */
#include "common/pg_prng.h"
/*
* POSTGRES backend dependent Constants.
*/
@@ -242,6 +245,13 @@ typedef enum
SERVER_TYPE_PREFER_STANDBY_PASS2 /* second pass - behaves same as ANY */
} PGTargetServerType;
/* Target server type (decoded value of load_balance_hosts) */
typedef enum
{
LOAD_BALANCE_DISABLE = 0, /* Use the existing host order (default) */
LOAD_BALANCE_RANDOM, /* Randomly shuffle the hosts */
} PGLoadBalanceType;
/* Boolean value plus a not-known state, for GUCs we might have to fetch */
typedef enum
{
@@ -398,6 +408,7 @@ struct pg_conn
char *ssl_max_protocol_version; /* maximum TLS protocol version */
char *target_session_attrs; /* desired session properties */
char *require_auth; /* name of the expected auth method */
char *load_balance_hosts; /* load balance over hosts */
/* Optional file to write trace info to */
FILE *Pfdebug;
@@ -469,6 +480,8 @@ struct pg_conn
/* Transient state needed while establishing connection */
PGTargetServerType target_server_type; /* desired session properties */
PGLoadBalanceType load_balance_type; /* desired load balancing
* algorithm */
bool try_next_addr; /* time to advance to next address/host? */
bool try_next_host; /* time to advance to next connhost[]? */
int naddr; /* number of addresses returned by getaddrinfo */
@@ -488,6 +501,8 @@ struct pg_conn
PGVerbosity verbosity; /* error/notice message verbosity */
PGContextVisibility show_context; /* whether to show CONTEXT field */
PGlobjfuncs *lobjfuncs; /* private state for large-object access fns */
pg_prng_state prng_state; /* prng state for load balancing connections */
/* Buffer for data received from backend and not yet processed */
char *inBuffer; /* currently allocated buffer */