From 1646bc798789e59358a333f032bc880443a15b79 Mon Sep 17 00:00:00 2001 From: DaMandal0rian Date: Thu, 19 Dec 2024 18:04:28 +0300 Subject: [PATCH] add pgcat connection pooler/proxy to indexer stack --- .env | 2 +- docker-compose.yml | 19 ++++++- indexers/db/pgcat.toml | 115 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 indexers/db/pgcat.toml diff --git a/.env b/.env index 7fef1ed1f..9fdac89f5 100644 --- a/.env +++ b/.env @@ -15,7 +15,7 @@ NODE_DOCKER_TAG=mainnet-2024-nov-13 DB_USER=postgres DB_DATABASE=postgres DB_PASSWORD=postgres -DB_PORT=5432 +DB_PORT=6432 DB_HOST=postgres # Mainnet diff --git a/docker-compose.yml b/docker-compose.yml index e1b86e031..e21fb62ad 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -68,6 +68,23 @@ services: interval: 30s retries: 60 +# PGCat Proxy + pgcat: + image: ghcr.io/postgresml/pgcat:e1e4929d439313d987c352b4517a6d99627f3e9c + command: + - "pgcat" + - "/etc/pgcat/pgcat.toml" + volumes: + - "./indexers/db/pgcat.toml:/etc/pgcat/pgcat.toml" + ports: + - "5432:5432" + - "9930:9930" + healthcheck: + test: ["CMD", "pgcat", "--version"] + interval: 10s + timeout: 5s + retries: 3 + # Postgres Database postgres: image: postgres:16-alpine @@ -84,7 +101,7 @@ services: POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_MAX_CONNECTIONS: 500 ports: - - "${DB_PORT}:5432" + - "${DB_PORT}:6432" healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s diff --git a/indexers/db/pgcat.toml b/indexers/db/pgcat.toml new file mode 100644 index 000000000..cce07be2e --- /dev/null +++ b/indexers/db/pgcat.toml @@ -0,0 +1,115 @@ +# +# PgCat configuration file +# + +# +# General pooler settings +[general] +# What IP to run on, 0.0.0.0 means accessible from everywhere. +host = "0.0.0.0" + +# Port to run on, same as PgBouncer used in this example. +port = 5432 + +# Whether to enable prometheus exporter or not. +enable_prometheus_exporter = true + +# Port at which prometheus exporter listens on. +prometheus_exporter_port = 9930 + +# How long to wait before aborting a server connection (ms). +connect_timeout = 5000 + +# How much time to give `SELECT 1` health check query to return with a result (ms). +healthcheck_timeout = 1000 + +# How long to keep connection available for immediate re-use, without running a healthcheck query on it +healthcheck_delay = 30000 + +# How much time to give clients during shutdown before forcibly killing client connections (ms). +shutdown_timeout = 60000 + +# For how long to ban a server if it fails a health check (seconds). +ban_time = 60 # seconds + +# If we should log client connections +log_client_connections = false + +# If we should log client disconnections +log_client_disconnections = false + +# TLS +# tls_certificate = "server.cert" +# tls_private_key = "server.key" + +# Credentials to access the virtual administrative database (pgbouncer or pgcat) +# Connecting to that database allows running commands like `SHOW POOLS`, `SHOW DATABASES`, etc.. +admin_username = "postgres" +admin_password = "postgres" + +# pool +# configs are structured as pool. +# the pool_name is what clients use as database name when connecting +# For the example below a client can connect using "postgres://sharding_user:sharding_user@pgcat_host:pgcat_port/sharded" +[pools.postgres] +# Pool mode (see PgBouncer docs for more). +# session: one server connection per connected client +# transaction: one server connection per client transaction +pool_mode = "transaction" + +# If the client doesn't specify, route traffic to +# this role by default. +# +# any: round-robin between primary and replicas, +# replica: round-robin between replicas only without touching the primary, +# primary: all queries go to the primary unless otherwise specified. +default_role = "any" + +# Query parser. If enabled, we'll attempt to parse +# every incoming query to determine if it's a read or a write. +# If it's a read query, we'll direct it to a replica. Otherwise, if it's a write, +# we'll direct it to the primary. +query_parser_enabled = true + +# If the query parser is enabled and this setting is enabled, we'll attempt to +# infer the role from the query itself. +query_parser_read_write_splitting = true + +# If the query parser is enabled and this setting is enabled, the primary will be part of the pool of databases used for +# load balancing of read queries. Otherwise, the primary will only be used for write +# queries. The primary can always be explicitly selected with our custom protocol. +primary_reads_enabled = true + +# So what if you wanted to implement a different hashing function, +# or you've already built one and you want this pooler to use it? +# +# Current options: +# +# pg_bigint_hash: PARTITION BY HASH (Postgres hashing function) +# sha1: A hashing function based on SHA1 +# +sharding_function = "pg_bigint_hash" + +# Credentials for users that may connect to this cluster +[pools.postgres.users.0] +username = "postgres" +password = "postgres" +# Maximum number of server connections that can be established for this user +# The maximum number of connection from a single Pgcat process to any database in the cluster +# is the sum of pool_size across all users. +pool_size = 9 + +# Maximum query duration. Dangerous, but protects against DBs that died in a non-obvious way. +statement_timeout = 0 + +# Shard 0 +[pools.postgres.shards.0] +# [ host, port, role ] +servers = [ + [ "postgres", 5432, "primary" ], +# [ "postgres", 5432, "replica" ] +] +# Database name (e.g. "postgres") +database = "postgres" + +database = "postgres"