at 25.11-pre 4.1 kB view raw
1{ 2 pkgs, 3 makeTest, 4 genTests, 5}: 6 7let 8 inherit (pkgs) lib; 9 10 makeTestFor = 11 package: 12 let 13 postgresqlDataDir = "/var/lib/postgresql/${package.psqlSchema}"; 14 replicationUser = "wal_receiver_user"; 15 replicationSlot = "wal_receiver_slot"; 16 replicationConn = "postgresql://${replicationUser}@localhost"; 17 baseBackupDir = "/var/cache/wals/pg_basebackup"; 18 walBackupDir = "/var/cache/wals/pg_wal"; 19 recoveryFile = pkgs.writeTextDir "recovery.signal" ""; 20 in 21 makeTest { 22 name = "postgresql-wal-receiver-${package.name}"; 23 meta.maintainers = with lib.maintainers; [ euxane ]; 24 25 nodes.machine = 26 { ... }: 27 { 28 systemd.tmpfiles.rules = [ 29 "d /var/cache/wals 0750 postgres postgres - -" 30 ]; 31 32 services.postgresql = { 33 inherit package; 34 enable = true; 35 settings = { 36 max_replication_slots = 10; 37 max_wal_senders = 10; 38 recovery_end_command = "touch recovery.done"; 39 restore_command = "cp ${walBackupDir}/%f %p"; 40 wal_level = "archive"; # alias for replica on pg >= 9.6 41 }; 42 authentication = '' 43 host replication ${replicationUser} all trust 44 ''; 45 initialScript = pkgs.writeText "init.sql" '' 46 create user ${replicationUser} replication; 47 select * from pg_create_physical_replication_slot('${replicationSlot}'); 48 ''; 49 }; 50 51 services.postgresqlWalReceiver.receivers.main = { 52 postgresqlPackage = package; 53 connection = replicationConn; 54 slot = replicationSlot; 55 directory = walBackupDir; 56 }; 57 # This is only to speedup test, it isn't time racing. Service is set to autorestart always, 58 # default 60sec is fine for real system, but is too much for a test 59 systemd.services.postgresql-wal-receiver-main.serviceConfig.RestartSec = lib.mkForce 5; 60 systemd.services.postgresql.serviceConfig.ReadWritePaths = [ "/var/cache/wals" ]; 61 }; 62 63 testScript = '' 64 # make an initial base backup 65 machine.wait_for_unit("postgresql") 66 machine.wait_for_unit("postgresql-wal-receiver-main") 67 # WAL receiver healthchecks PG every 5 seconds, so let's be sure they have connected each other 68 # required only for 9.4 69 machine.sleep(5) 70 machine.succeed( 71 "${package}/bin/pg_basebackup --dbname=${replicationConn} --pgdata=${baseBackupDir}" 72 ) 73 74 # create a dummy table with 100 records 75 machine.succeed( 76 "sudo -u postgres psql --command='create table dummy as select * from generate_series(1, 100) as val;'" 77 ) 78 79 # stop postgres and destroy data 80 machine.systemctl("stop postgresql") 81 machine.systemctl("stop postgresql-wal-receiver-main") 82 machine.succeed("rm -r ${postgresqlDataDir}/{base,global,pg_*}") 83 84 # restore the base backup 85 machine.succeed( 86 "cp -r ${baseBackupDir}/* ${postgresqlDataDir} && chown postgres:postgres -R ${postgresqlDataDir}" 87 ) 88 89 # prepare WAL and recovery 90 machine.succeed("chmod a+rX -R ${walBackupDir}") 91 machine.execute( 92 "for part in ${walBackupDir}/*.partial; do mv $part ''${part%%.*}; done" 93 ) # make use of partial segments too 94 machine.succeed( 95 "cp ${recoveryFile}/* ${postgresqlDataDir}/ && chmod 666 ${postgresqlDataDir}/recovery*" 96 ) 97 98 # replay WAL 99 machine.systemctl("start postgresql") 100 machine.wait_for_file("${postgresqlDataDir}/recovery.done") 101 machine.systemctl("restart postgresql") 102 machine.wait_for_unit("postgresql") 103 104 # check that our records have been restored 105 machine.succeed( 106 "test $(sudo -u postgres psql --pset='pager=off' --tuples-only --command='select count(distinct val) from dummy;') -eq 100" 107 ) 108 ''; 109 }; 110in 111genTests { inherit makeTestFor; }