From 5d21cecee78141c2a79106b188fcb986153fba56 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Thu, 29 Jul 2021 12:44:42 +0200 Subject: [PATCH] modules: services: postgres: add migration script The process to upgrade is: * Make sure the version number of the script is one major version over the service version. * Activate the script, rebuild configuration. * Run `upgrade-pg-cluster` as `root`. One can give arguments like `--link` or `--jobs 4` to speedup the process. See documentation for some details. * Change package to new version once the upgrade is finished, rebuild configuration. * Optionally, `ANALYZE` the new database. --- modules/services/postgresql.nix | 43 +++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/modules/services/postgresql.nix b/modules/services/postgresql.nix index 8da9ab7..3c06098 100644 --- a/modules/services/postgresql.nix +++ b/modules/services/postgresql.nix @@ -5,6 +5,9 @@ in { options.my.services.postgresql = with lib; { enable = my.mkDisableOption "postgres configuration"; + + # Transient option to be enabled for migrations + upgradeScript = mkEnableOption "postgres upgrade script"; }; config = lib.mkMerge [ @@ -14,5 +17,45 @@ in package = pkgs.postgresql_12; }; }) + + # Taken from the manual + (lib.mkIf cfg.upgradeScript { + containers.temp-pg.config.services.postgresql = { + enable = true; + package = pkgs.postgresql_13; + }; + + environment.systemPackages = + let + newpg = config.containers.temp-pg.config.services.postgresql; + in + [ + (pkgs.writeScriptBin "upgrade-pg-cluster" '' + #!/usr/bin/env bash + + set -x + export OLDDATA="${config.services.postgresql.dataDir}" + export NEWDATA="${newpg.dataDir}" + export OLDBIN="${config.services.postgresql.package}/bin" + export NEWBIN="${newpg.package}/bin" + + if [ "$OLDDATA" -ef "$NEWDATA" ]; then + echo "Cannot migrate to same data directory" >&2 + exit 1 + fi + + install -d -m 0700 -o postgres -g postgres "$NEWDATA" + cd "$NEWDATA" + sudo -u postgres $NEWBIN/initdb -D "$NEWDATA" + + systemctl stop postgresql # old one + + sudo -u postgres $NEWBIN/pg_upgrade \ + --old-datadir "$OLDDATA" --new-datadir "$NEWDATA" \ + --old-bindir $OLDBIN --new-bindir $NEWBIN \ + "$@" + '') + ]; + }) ]; }