Code change:
<title>Upgrading</title> <para> <del> FIXME: document dump/upgrade/load cycle. </del> <ins> Major PostgreSQL upgrade requires PostgreSQL downtime and a few imperative steps to be called. To simplify this process, use the following NixOS module: <programlisting> containers.temp-pg.config.services.postgresql = { enable = true; package = pkgs.postgresql_12; ## set a custom new dataDir # dataDir = "/some/data/dir"; }; environment.systemPackages = let newpg = config.containers.temp-pg.config.services.postgresql; in [ (pkgs.writeScriptBin "upgrade-pg-cluster" '' set -x export OLDDATA="${config.services.postgresql.dataDir}" export NEWDATA="${newpg.dataDir}" export OLDBIN="${config.services.postgresql.package}/bin" export NEWBIN="${newpg.package}/bin" 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  "$@" '') ]; </programlisting> </ins> </para> <ins> <para> The upgrade process is: </para> <orderedlist> <listitem> <para> Rebuild nixos configuration with the configuration above added to your <filename>configuration.nix</filename>. Alternatively, add that into separate file and reference it in <literal>imports</literal> list. </para> </listitem> <listitem> <para> Login as root (<literal>sudo su -</literal>) </para> </listitem> <listitem> <para> Run <literal>upgrade-pg-cluster</literal>. It will stop old postgresql, initialize new one and migrate old one to new one. You may supply arguments like <literal>--jobs 4</literal> and <literal>--link</literal> to speedup migration process. See <link xlink:href="https://www.postgresql.org/docs/current/pgupgrade.html" /> for details. </para> </listitem> <listitem> <para> Change postgresql package in NixOS configuration to the one you were upgrading to, and change <literal>dataDir</literal> to the one you have migrated to. Rebuild NixOS. This should start new postgres using upgraded data directory. </para> </listitem> <listitem> <para> After upgrade you may want to <literal>ANALYZE</literal> new db. </para> </listitem> </orderedlist> </ins> </section> <section xml:id="module-services-postgres-options"> <title>Options</title> <para> <del> A complete list of options for the PostgreSQL module may be found <link linkend="opt-services.postgresql.enable">here</link>. </del> <ins> A complete list of options for the PostgreSQL module may be found <link linkend="opt-services.postgresql.enable">here</link>. </ins> </para> </section> <section xml:id="module-services-postgres-plugins"> <title>Plugins</title> <para> <del> Plugins collection for each PostgreSQL version can be accessed with <literal>.pkgs</literal>. For example, for <literal>pkgs.postgresql_11</literal> package, its plugin collection is accessed by <literal>pkgs.postgresql_11.pkgs</literal>: </del> <ins> Plugins collection for each PostgreSQL version can be accessed with <literal>.pkgs</literal>. For example, for <literal>pkgs.postgresql_11</literal> package, its plugin collection is accessed by <literal>pkgs.postgresql_11.pkgs</literal>: </ins> <screen> <prompt>$ </prompt>nix repl '&lt;nixpkgs&gt;'

Related discussion:
text: I tried to follow procedure above, but as I mentioned before, to use as suggested I needed to change the PostgreSQL user mapping in the Hydra module as specified in my comment just above this one, otherwise I would get a message. However, to read the database dump back into the new PostgreSQL installation I had to change the user mapping as follows: ... and then, after activating the configuration, I needed to run the command in the following way (as root): After doing this, the upgrade from PostgreSQL 9.4 to 9.6 seems to have completed successfully.
Related
If anyone else stumbles on this, pgupgrade seems to work now. I realized after upgrade that my db got reinitialized, so steps for me were much more brutish than that post, but in a nutshell: with new postgresql running, clear whatever got reinitialized (pgupgrade won't run if there are data around, but won't tell you what to remove... lists databases, don't know how to list users, I guessed) drop database whatever; drop user whatever; stop postgresql.service figure path for old binaries, e.g. and copy it somewhere. run the actual pgupgrade as user: restart the postgresql service if all went well after some testing pgupgrade suggests removing the old db with (disclaimer: Don't blame me if that eats your data)