summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaximilian Bosch <maximilian@mbosch.me>2024-11-17 19:46:54 +0100
committergithub-actions[bot] <github-actions[bot]@users.noreply.github.com>2024-11-23 08:20:34 +0000
commitaa88b3cae5a9174c520b49ecb4e0ba48015ea65b (patch)
treef0ccb7e2d4b0d1a39c36eeb1fab239cfe3df8b10
parent[Backport release-24.11] nixos/scx: init module (#357622) (diff)
downloadnixpkgs-origin/backport-356965-to-release-24.11.tar.gz
nixos/pgbouncer: rework RFC42 integrationorigin/backport-356965-to-release-24.11
Commit bfb9d1825d545d96278db84d43e0b2a529775089 added RFC42 support which is a good thing in general, but this implementation has the following flaws: * `services.pgbouncer.logFile` was not renamed to `[...].log_file`, but to `[...].logfile`. Also the use of `mkRenamedOptionModule` is inappropriate here because the two options are not equivalent: the old option took a path relative to the home directory, the new an absolute path. * Using `mkRenamedOptionModule` with options that don't exist (but are keys in a freeform attr-set or an `attrsOf X`), you get the following error when referencing an option you didn't declare: error: evaluation aborted with the following error message: 'Renaming error: option `services.pgbouncer.settings.pgbouncer.listen_port' does not exist.' This error is pretty bad because it's not actionable for an end-user of the module. A possible use-case is doing networking.firewall.allowedTCPPorts = [ config.services.pgbouncer.listenPort ]; without specifying a custom listen port. This is an example of why you want to keep options, they already contain defaults and you can re-use those defaults in other parts of your system configuration. I decided to re-add a bunch of options where I figured that it's either useful to be able to address those in the NixOS configuration or having documentation directly in the options' reference in the NixOS manual. I didn't add all options, I'll leave that to the maintainers of pgbouncer. (cherry picked from commit 2995b3825e141887018569a48381b498baef1573)
-rw-r--r--nixos/modules/services/databases/pgbouncer.nix188
1 files changed, 184 insertions, 4 deletions
diff --git a/nixos/modules/services/databases/pgbouncer.nix b/nixos/modules/services/databases/pgbouncer.nix
index 7eafa502eb0c..36130d66c685 100644
--- a/nixos/modules/services/databases/pgbouncer.nix
+++ b/nixos/modules/services/databases/pgbouncer.nix
@@ -3,14 +3,20 @@ let
cfg = config.services.pgbouncer;
settingsFormat = pkgs.formats.ini { };
- configFile = settingsFormat.generate "pgbouncer.ini" cfg.settings;
+ configFile = settingsFormat.generate "pgbouncer.ini"
+ (lib.filterAttrsRecursive (_: v: v != null) cfg.settings);
configPath = "pgbouncer/pgbouncer.ini";
in
{
imports = [
- (lib.mkRenamedOptionModule
+ (lib.mkRemovedOptionModule
[ "services" "pgbouncer" "logFile" ]
- [ "services" "pgbouncer" "settings" "pgbouncer" "log_file" ])
+ ''
+ `services.pgbouncer.logFile` has been removed, use `services.pgbouncer.settings.pgbouncer.logfile`
+ instead.
+ Please note that the new option expects an absolute path
+ whereas the old option accepted paths relative to pgbouncer's home dir.
+ '')
(lib.mkRenamedOptionModule
[ "services" "pgbouncer" "listenAddress" ]
[ "services" "pgbouncer" "settings" "pgbouncer" "listen_addr" ])
@@ -128,7 +134,181 @@ in
};
settings = lib.mkOption {
- type = settingsFormat.type;
+ type = lib.types.submodule {
+ freeformType = settingsFormat.type;
+ options = {
+ pgbouncer = {
+ listen_port = lib.mkOption {
+ type = lib.types.port;
+ default = 6432;
+ description = ''
+ Which port to listen on. Applies to both TCP and Unix sockets.
+ '';
+ };
+
+ listen_addr = lib.mkOption {
+ type = lib.types.nullOr lib.types.commas;
+ example = "*";
+ default = null;
+ description = ''
+ Specifies a list (comma-separated) of addresses where to listen for TCP connections.
+ You may also use * meaning “listen on all addresses”.
+ When not set, only Unix socket connections are accepted.
+
+ Addresses can be specified numerically (IPv4/IPv6) or by name.
+ '';
+ };
+
+ pool_mode = lib.mkOption {
+ type = lib.types.enum [ "session" "transaction" "statement" ];
+ default = "session";
+ description = ''
+ Specifies when a server connection can be reused by other clients.
+
+ session
+ Server is released back to pool after client disconnects. Default.
+ transaction
+ Server is released back to pool after transaction finishes.
+ statement
+ Server is released back to pool after query finishes.
+ Transactions spanning multiple statements are disallowed in this mode.
+ '';
+ };
+
+ max_client_conn = lib.mkOption {
+ type = lib.types.int;
+ default = 100;
+ description = ''
+ Maximum number of client connections allowed.
+
+ When this setting is increased, then the file descriptor limits in the operating system
+ might also have to be increased. Note that the number of file descriptors potentially
+ used is more than maxClientConn. If each user connects under its own user name to the server,
+ the theoretical maximum used is:
+ maxClientConn + (max pool_size * total databases * total users)
+
+ If a database user is specified in the connection string (all users connect under the same user name),
+ the theoretical maximum is:
+ maxClientConn + (max pool_size * total databases)
+
+ The theoretical maximum should never be reached, unless somebody deliberately crafts a special load for it.
+ Still, it means you should set the number of file descriptors to a safely high number.
+ '';
+ };
+
+ default_pool_size = lib.mkOption {
+ type = lib.types.int;
+ default = 20;
+ description = ''
+ How many server connections to allow per user/database pair.
+ Can be overridden in the per-database configuration.
+ '';
+ };
+
+ max_db_connections = lib.mkOption {
+ type = lib.types.int;
+ default = 0;
+ description = ''
+ Do not allow more than this many server connections per database (regardless of user).
+ This considers the PgBouncer database that the client has connected to,
+ not the PostgreSQL database of the outgoing connection.
+
+ This can also be set per database in the [databases] section.
+
+ Note that when you hit the limit, closing a client connection to one pool will
+ not immediately allow a server connection to be established for another pool,
+ because the server connection for the first pool is still open.
+ Once the server connection closes (due to idle timeout),
+ a new server connection will immediately be opened for the waiting pool.
+
+ 0 = unlimited
+ '';
+ };
+
+ max_user_connections = lib.mkOption {
+ type = lib.types.int;
+ default = 0;
+ description = ''
+ Do not allow more than this many server connections per user (regardless of database).
+ This considers the PgBouncer user that is associated with a pool,
+ which is either the user specified for the server connection
+ or in absence of that the user the client has connected as.
+
+ This can also be set per user in the [users] section.
+
+ Note that when you hit the limit, closing a client connection to one pool
+ will not immediately allow a server connection to be established for another pool,
+ because the server connection for the first pool is still open.
+ Once the server connection closes (due to idle timeout), a new server connection
+ will immediately be opened for the waiting pool.
+
+ 0 = unlimited
+ '';
+ };
+
+ ignore_startup_parameters = lib.mkOption {
+ type = lib.types.nullOr lib.types.commas;
+ example = "extra_float_digits";
+ default = null;
+ description = ''
+ By default, PgBouncer allows only parameters it can keep track of in startup packets:
+ client_encoding, datestyle, timezone and standard_conforming_strings.
+
+ All others parameters will raise an error.
+ To allow others parameters, they can be specified here, so that PgBouncer knows that
+ they are handled by the admin and it can ignore them.
+
+ If you need to specify multiple values, use a comma-separated list.
+
+ IMPORTANT: When using prometheus-pgbouncer-exporter, you need:
+ extra_float_digits
+ <https://github.com/prometheus-community/pgbouncer_exporter#pgbouncer-configuration>
+ '';
+ };
+ };
+ databases = lib.mkOption {
+ type = lib.types.attrsOf lib.types.str;
+ default = {};
+ example = {
+ exampledb = "host=/run/postgresql/ port=5432 auth_user=exampleuser dbname=exampledb sslmode=require";
+ bardb = "host=localhost dbname=bazdb";
+ foodb = "host=host1.example.com port=5432";
+ };
+ description = ''
+ Detailed information about PostgreSQL database definitions:
+ <https://www.pgbouncer.org/config.html#section-databases>
+ '';
+ };
+ users = lib.mkOption {
+ type = lib.types.attrsOf lib.types.str;
+ default = {};
+ example = {
+ user1 = "pool_mode=session";
+ };
+ description = ''
+ Optional.
+
+ Detailed information about PostgreSQL user definitions:
+ <https://www.pgbouncer.org/config.html#section-users>
+ '';
+ };
+
+ peers = lib.mkOption {
+ type = lib.types.attrsOf lib.types.str;
+ default = {};
+ example = {
+ "1" = "host=host1.example.com";
+ "2" = "host=/tmp/pgbouncer-2 port=5555";
+ };
+ description = ''
+ Optional.
+
+ Detailed information about PostgreSQL database definitions:
+ <https://www.pgbouncer.org/config.html#section-peers>
+ '';
+ };
+ };
+ };
default = { };
description = ''
Configuration for PgBouncer, see <https://www.pgbouncer.org/config.html>