Skip to content

Commit

Permalink
maintenance: add postgresql schema update guide
Browse files Browse the repository at this point in the history
  • Loading branch information
erikarvstedt committed Jul 8, 2022
1 parent 8969ed9 commit 958e7a5
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 1 deletion.
13 changes: 12 additions & 1 deletion deployment/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,16 @@
modules = [ ../base.nix ];
}).config.system.build.toplevel;
};
});
}) // {
nixosConfigurations = {
base = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ../base.nix ];
};
};

lib = {
postgresql = import ../maintenance/update-postgresql.nix self.nixosConfigurations.base;
};
};
}
50 changes: 50 additions & 0 deletions maintenance/maintenance.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,53 @@ xdg-open http://localhost:10000
# btcpayserver
gpg --decrypt ../secrets/client-side/btcpayserver-credentials.gpg 2>/dev/null
xdg-open http://localhost:10001/btcpayserver

#―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
# Update postgresql database schema
# Required when the postgresql version is updated when changing `system.stateVersion`
# See also: https://nixos.org/manual/nixos/stable/index.html#module-services-postgres-upgrading

# The system state version that postgresql should be updated to
newSystemStateVersion=22.05

# Build script
drv=$(nix eval --raw ../deployment#lib --apply "lib: (lib.postgresql.updateSystem \"$newSystemStateVersion\").drvPath")
script=$(nix build --no-link --print-out-paths $drv)

# Check postgresql versions in script
# See also: https://www.postgresql.org/docs/current/pgupgrade.html
# By using option `--link` for `pg_upgrade`, db files are hardlinked when
# the datadir for the new schema is created
cat $script

# Run script
nix copy --to ssh://nixbitcoin.org $script
time ssh nixbitcoin.org $script

# Now change `system.stateVersion` to $newSystemStateVersion in ../base.nix and deploy

# Check postgresql
ssh nixbitcoin.org 'systemctl status postgresql'

# Run recommended analyzer script
schema=$(nix eval --raw ../deployment#lib.postgresql.systemPostgresqlSchema)
echo $schema
ssh nixbitcoin.org "sudo -u postgres /var/lib/postgresql/$schema/analyze_new_cluster.sh"

# Delete old data dir
ssh nixbitcoin.org "sudo -u postgres /var/lib/postgresql/$schema/delete_old_cluster.sh"

ssh nixbitcoin.org 'ls -al /var/lib/postgresql'

### Appendix
# The update step runs pretty fast (~10s)
# Example:
# Update the postgresql datadir from schema 11.1 to 14 (2022-07-02)
ssh nixbitcoin.org 'du -sh --apparent /var/lib/postgresql/11.1' # => 47G
# Duration:
# real 0m10.088s

ssh nixbitcoin.org 'ls -al /var/lib/postgresql'

# Undo migration (requires that postgresql was not run with the new datadir.)
ssh nixbitcoin.org 'mv /var/lib/postgresql/<schema>/global/pg_control{.old,}'
48 changes: 48 additions & 0 deletions maintenance/update-postgresql.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
baseSystemConfig:
rec {
updatePostgresql = { pkgs, postgresqlOld, postgresqlNew }:
pkgs.writers.writeBash "update-postgresql" ''
set -euxo pipefail
systemctl stop postgresql
oldData="/var/lib/postgresql/${postgresqlOld.psqlSchema}"
newData="/var/lib/postgresql/${postgresqlNew.psqlSchema}"
oldBin="${postgresqlOld}/bin"
newBin="${postgresqlNew}/bin"
install -d -m 700 -o postgres -g postgres "$newData"
cd "$newData"
sudo -u postgres $newBin/initdb -D "$newData"
sudo -u postgres $newBin/pg_upgrade \
--old-datadir "$oldData" --new-datadir "$newData" \
--old-bindir $oldBin --new-bindir $newBin \
--jobs $(nproc) \
--link \
"$@"
'';

# Todo: Use the main system here when we've switched to flake-based deployment
base = baseSystemConfig;

baseWithPostgresql = base.extendModules {
modules = [{ services.postgresql.enable = true; }];
};

updateSystem = newSystemStateVersion:
let
baseNewStateVersion = baseWithPostgresql.extendModules {
modules = [ ({ lib, ... }: {
system.stateVersion = lib.mkForce newSystemStateVersion;
})];
};
in
updatePostgresql {
pkgs = base.pkgs;
postgresqlOld = baseWithPostgresql.config.services.postgresql.package;
postgresqlNew = baseNewStateVersion.config.services.postgresql.package;
};

systemPostgresqlSchema = baseWithPostgresql.config.services.postgresql.package.psqlSchema;
}

0 comments on commit 958e7a5

Please sign in to comment.