From 59d147527f6b8ba406787ea6cc95cbbcd92bc87d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Mon, 5 May 2025 00:57:42 +0200 Subject: [PATCH 1/3] postgres: add pgRepackTimer option --- modules/postgres.nix | 45 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/modules/postgres.nix b/modules/postgres.nix index f0f8866..96fc3ba 100644 --- a/modules/postgres.nix +++ b/modules/postgres.nix @@ -36,6 +36,28 @@ in }); }; + pgRepackTimer = { + enable = libS.mkOpinionatedOption "install pg_repack and configure a systemd timer to run it periodically on all DBs"; + + timerConfig = lib.mkOption { + type = lib.types.nullOr (lib.types.attrsOf utils.systemdUtils.unitOptions.unitOption); + default = { + OnCalendar = "02:00"; + Persistent = true; + RandomizedDelaySec = "10m"; + }; + example = { + OnCalendar = "06:00"; + Persistent = true; + RandomizedDelaySec = "5h"; + }; + description = '' + When to run the VACUUM ANALYZE. + See {manpage}`systemd.timer(5)` for details. + ''; + }; + }; + preloadAllExtensions = libS.mkOpinionatedOption "load all installed extensions through `shared_preload_libraries`"; recommendedDefaults = libS.mkOpinionatedOption "set recommended default settings"; @@ -194,6 +216,7 @@ in postgresql = { databases = [ "postgres" ] ++ config.services.postgresql.ensureDatabases; enableJIT = lib.mkIf cfg.recommendedDefaults true; + extensions = ps: with ps; lib.mkIf cfg.pgRepackTimer [ pg_repack ]; settings.shared_preload_libraries = lib.optional cfg.configurePgStatStatements "pg_stat_statements" # TODO: upstream, this probably requires a new entry in passthru to pick if the object name doesn't match the plugin name or there are multiple @@ -305,6 +328,16 @@ in stopIfChanged = lib.mkIf cfg.recommendedDefaults false; }; + postgresql-pg-repack = lib.mkIf cfg.vacuumAnalyzeTimer.enable { + description = "Repack all PostgreSQL databases"; + after = [ "postgresql.service" ]; + serviceConfig = { + ExecStart = "${lib.getExe cfg.package.pkgs.pg_repack} --port=${builtins.toString cfg.settings.port} --all"; + User = "postgres"; + }; + wantedBy = [ "timers.target" ]; + }; + postgresql-vacuum-analyze = lib.mkIf cfg.vacuumAnalyzeTimer.enable { description = "Vacuum and analyze all PostgreSQL databases"; after = [ "postgresql.service" ]; @@ -317,9 +350,15 @@ in }; }; - timers.postgresql-vacuum-analyze = lib.mkIf cfg.vacuumAnalyzeTimer.enable { - inherit (cfg.vacuumAnalyzeTimer) timerConfig; - wantedBy = [ "timers.target" ]; + timers = { + postgresql-pg-repack = lib.mkIf cfg.pgRepackTimer.enable { + inherit (cfg.vacuumAnalyzeTimer) timerConfig; + wantedBy = [ "timers.target" ]; + }; + postgresql-vacuum-analyze = lib.mkIf cfg.vacuumAnalyzeTimer.enable { + inherit (cfg.vacuumAnalyzeTimer) timerConfig; + wantedBy = [ "timers.target" ]; + }; }; }; }; From 10c8c14182c5be192c71c7780887d2dfb0974c25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Mon, 5 May 2025 00:58:08 +0200 Subject: [PATCH 2/3] postgres: reduce vacuum randomness, don't restart postgres on changes --- modules/postgres.nix | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/postgres.nix b/modules/postgres.nix index 96fc3ba..61c3aca 100644 --- a/modules/postgres.nix +++ b/modules/postgres.nix @@ -115,14 +115,14 @@ in }; vacuumAnalyzeTimer = { - enable = libS.mkOpinionatedOption "timer to run VACUUM ANALYZE on all DBs"; + enable = libS.mkOpinionatedOption "configure a systemd timer to run `VACUUM ANALYZE` periodically on all DBs"; timerConfig = lib.mkOption { type = lib.types.nullOr (lib.types.attrsOf utils.systemdUtils.unitOptions.unitOption); default = { OnCalendar = "03:00"; Persistent = true; - RandomizedDelaySec = "30m"; + RandomizedDelaySec = "10m"; }; example = { OnCalendar = "06:00"; @@ -216,7 +216,7 @@ in postgresql = { databases = [ "postgres" ] ++ config.services.postgresql.ensureDatabases; enableJIT = lib.mkIf cfg.recommendedDefaults true; - extensions = ps: with ps; lib.mkIf cfg.pgRepackTimer [ pg_repack ]; + extensions = lib.mkIf cfg.pgRepackTimer.enable (ps: with ps; [ pg_repack ]); settings.shared_preload_libraries = lib.optional cfg.configurePgStatStatements "pg_stat_statements" # TODO: upstream, this probably requires a new entry in passthru to pick if the object name doesn't match the plugin name or there are multiple @@ -341,7 +341,6 @@ in postgresql-vacuum-analyze = lib.mkIf cfg.vacuumAnalyzeTimer.enable { description = "Vacuum and analyze all PostgreSQL databases"; after = [ "postgresql.service" ]; - requires = [ "postgresql.service" ]; serviceConfig = { ExecStart = "${lib.getExe' cfg.package "psql"} --port=${builtins.toString cfg.settings.port} -tAc 'VACUUM ANALYZE'"; User = "postgres"; From aff281ce66d8db31ed6f35959586878b87d66f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sandro=20J=C3=A4ckel?= Date: Sat, 10 May 2025 00:39:55 +0200 Subject: [PATCH 3/3] postgres: filter out fake jit extension --- modules/postgres.nix | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/postgres.nix b/modules/postgres.nix index 61c3aca..6b0056a 100644 --- a/modules/postgres.nix +++ b/modules/postgres.nix @@ -233,8 +233,10 @@ in name = lib.getName so; in { postgis = "postgis-3"; + # withJIT installs the postgres' jit output as an extension but that is no shared object to load + postgresql = null; }.${name} or name; - in lib.optionals cfg.preloadAllExtensions (map getSoOrFallback finalPackage.installedExtensions)); + in lib.optionals cfg.preloadAllExtensions (lib.filter (x: x != null) (map getSoOrFallback finalPackage.installedExtensions))); upgrade.stopServices = with config.services; lib.mkMerge [ (lib.mkIf (atuin.enable && atuin.database.createLocally) [ "atuin" ]) (lib.mkIf (gancio.enable && gancio.settings.db.dialect == "postgres") [ "gancio" ])