I'm going to migrate a production PostgreSQL 12 database (~200GB) to another more powerful server. There are a bunch of partitioned tables, some without primary key (theoretically, it won't be a problem to temporarily add them if needed).
Is there any solution to migrate without or at least with the smallest downtime?
As @FrankHeikens wrote in the comment to the question, we need to configure master-standby replication.
Here are steps on master (Postgres 12):
NOTE: All commands run on behalf of a user with sudo permissions.
psql -U postgres
CREATE ROLE replication WITH REPLICATION PASSWORD 'REPLICATION_USER_PASSWORD' LOGIN;
sudo nano /etc/postgresql/12/main/pg_hba.conf
# Add the following line
> To Existing Server
host replication replication STANDBY_SERVER_IP/32 md5
NOTE: wal_keep_segments should be as much enough to keep wal files while base backup is in progress.
sudo nano /etc/postgresql/12/main/postgres.conf
# Uncomment and edit values
listen_addresses = '*'
wal_level = replica
wal_keep_segments = 256 # (each segment is 16 MB by default, so ~5GB of free space is need **for our case**)
max_wal_senders = 2 # (for case of single standby)
max_replication_slots = 2 # (for case of single standby)
hot_standby = on
hot_standby_feedback = on
Open Postgres network port (5432 by default) in a system firewall.
Restart Posgtres
sudo service postgresql restart
Here are steps on standby (Postgres 12):
NOTE: All commands run on behalf of a user with sudo permissions.
sudo service postgresql stop
sudo rm /var/log/postgresql/*
sudo rm -rf /var/lib/postgresql/12/main/*
# Ensure that cleaning up is none
sudo du -sh /var/lib/postgresql/12/main/
sudo nano /etc/postgresql/12/main/postgres.conf
# Uncomment and edit values
hot_standby = on
primary_conninfo = 'user=replication password=<REPLICATION_USER_PASSWORD> host=MASTER_SERVER_IP port=5432'
cd /etc/postgresql/12/main/
sudo touch standby.signal
sudo chown postgres:postgres standby.signal
# Enter 2 passwords: for local 'postgres' user and then for remote 'replication' user
su - postgres -c "pg_basebackup --host=MASTER_SERVER_IP --username=replication --pgdata=/var/lib/postgresql/12/main --wal-method=stream --write-recovery-conf"
sudo service postgresql start
To check the progress of replication:
psql -U postgres
# On master
select * from pg_stat_replication;
# On standby
select * from pg_stat_wal_receiver;
To promote standby server to master mode:
psql -U postgres
select pg_promote();