The light cycle maze 4 End of line 5 I fight for the users Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest 2 / 63
With one tiny little catch... No built in mechanism for automating backups or failover Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest Greetings, programs! 4 / 63
Cthulhu summoning... Automated with third party tools repmgr pg auto failover PostgreSQL Automatic Failover (PAF) Patroni Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest Greetings, programs! 5 / 63
python by Zalando. The tool relies on a distributed consensus store (DCS) to maintain the cluster status. Patroni is available in the pgdg official repository. Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest Greetings, programs! 6 / 63
for PostgreSQL stored in DCS Very resilient to split brain HAProxy for connection routed via api check Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest Greetings, programs! 8 / 63
unclear (but the community is very helpful) The client works only in interactive mode In order to automate the api call you’ll need to build your api call (e.g. curl, ansible uri module...) Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest Greetings, programs! 9 / 63
tools like pg basebackup barman WAL-E/WAL-G pgBackRest Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest Greetings, programs! 10 / 63
automatic the backups. pgBackRest is a community driven project. Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest Greetings, programs! 11 / 63
Parallel jobs configurable Can backup from the standby servers Async WAL push and pull Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest Greetings, programs! 12 / 63
ini style configuration Available in deb/yum pgdg repositories Cloud backup options GCP/S3/Azure Multiple repositories configurable Self contained backup repository Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest Greetings, programs! 13 / 63
of when configuring archive-push-queue-max. There is the risk of wal files not being archived if the limit is reached. Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest Greetings, programs! 14 / 63
Fercot’s Talk Unleash the Power within pgBackRest https://www.youtube.com/watch?v=eyda4r6T3Ek Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest Greetings, programs! 16 / 63
GCP and a GCP bucket patroni-0 patroni-1 patroni-2 Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The grid 19 / 63
Install etcd on the nodes Configure and start etcd Install PostgreSQL 14 and patroni on the nodes Configure patroni Start patroni Profit Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The grid 20 / 63
We need to download the archive from github and configure it. Example configuration file for patroni-0 #[Member] ETCD_DATA_DIR="/var/lib/etcd/data" ETCD_LISTEN_PEER_URLS="http://10.164.0.3:2380" ETCD_LISTEN_CLIENT_URLS="http://10.164.0.3:2379" ETCD_NAME="patroni-0" #must be unique within the etcd cluster #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.164.0.3:2380" ETCD_ADVERTISE_CLIENT_URLS="http://10.164.0.3:2379" ETCD_INITIAL_CLUSTER="patroni-0=http://10.164.0.3:2380,patroni-1=http://10.164.0.2:2380,patroni-2 =http://10.164.0.4:2380" Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The grid 23 / 63
Wants=network-online.target [Service] Type=notify WorkingDirectory=/var/lib/etcd EnvironmentFile=-/etc/etcd_config.env User=etcd # set GOMAXPROCS to number of processors ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /usr/local/bin/etcd " Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The grid 24 / 63
etcd sudo systemctl start etcd [ansible@patroni -0 ~]$ etcdctl --endpoints "http ://10.164.0.3:2379" --cluster=true endpoint health http ://10.164.0.3:2379 is healthy: successfully committed proposal: took = 3.468686 ms http ://10.164.0.2:2379 is healthy: successfully committed proposal: took = 3.946757 ms http ://10.164.0.4:2379 is healthy: successfully committed proposal: took = 14.749053 ms Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The grid 25 / 63
the directory /etc/patroni Then add a new configuration file into the directory named patroni.yml scope: f l y n n namespace: / t h e _ g r i d / name: p a t r o n i - 0 log: dir: / v a r / l o g / p a t r o n i restapi: listen: 1 0 . 1 6 4 . 0 . 3 : 8 0 0 8 connect_address: 1 0 . 1 6 4 . 0 . 3 : 8 0 0 8 etcd3: hosts: 1 0 . 1 6 4 . 0 . 3 : 2 3 7 9 , 1 0 . 1 6 4 . 0 . 2 : 2 3 7 9 , 1 0 . 1 6 4 . 0 . 4 : 2 3 7 9 bootstrap: dcs: ttl: 1 0 loop_wait: 1 0 retry_timeout: 1 0 Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The grid 28 / 63
5 7 6 postgresql: use_pg_rewind: t r u e use_slots: f a l s e parameters: wal_level: ’ r e p l i c a ’ archive_mode: ’ o n ’ archive_command: ’ / b i n / t r u e ’ unix_socket_directories: ’ / v a r / r u n / p o s t g r e s q l / . ’ max_connections: " 1 0 0 " shared_buffers: " 2 5 6 M B " work_mem: " 8 M B " maintenance_work_mem: " 1 6 M B " password_encryption: " s c r a m - s h a - 2 5 6 " method: i n i t d b # some desired options for ’initdb ’ initdb: # N o t e : I t n e e d s t o b e a l i s t ( s o m e o p t i o n s n e e d v a l u e s , o t h e r s a r e s w i t c h e s ) - encoding: U T F 8 Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The grid 29 / 63
A d d f o l l o w i n g l i n e s t o p g _ h b a . c o n f a f t e r r u n n i n g ’ i n i t d b ’ - host replication replicator 0.0.0.0/0 scram -sha -256 - host all all 0.0.0.0/0 scram -sha -256 # Some additional users users which needs to be created after initializing new cluster users: Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The grid 30 / 63
5 4 3 2 " connect_address: p a t r o n i - 0 : 5 4 3 2 data_dir: / v a r / l i b / p g s q l / d a t a / p o s t g r e s q l 1 4 bin_dir: / u s r / p g s q l - 1 4 / b i n / # config_dir: pgpass: / t m p / p g p a s s 0 pg_hba: - local all all peer - host all all 127.0.0.1/32 scram -sha -256 - host all all :: 1 / 1 2 8 s c r a m - s h a - 2 5 6 - host replication replicator :: 1 / 1 2 8 s c r a m - s h a - 2 5 6 - host replication replicator 0.0.0.0/0 scram -sha -256 - host all all 0.0.0.0/0 scram -sha -256 authentication: replication: username: r e p l i c a t o r password: S E C R E T superuser: username: p o s t g r e s Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The grid 31 / 63
R _ S E C R E T rewind: # H a s n o e f f e c t o n p o s t g r e s 1 0 a n d l o w e r username: r e w i n d _ u s e r password: V E R Y _ S E C R E T parameters: wal_level: ’ r e p l i c a ’ archive_mode: ’ o n ’ unix_socket_directories: ’ / v a r / r u n / p o s t g r e s q l / . ’ max_connections: " 1 0 0 " shared_buffers: " 2 5 6 M B " work_mem: " 8 M B " maintenance_work_mem: " 1 6 M B " password_encryption: " s c r a m - s h a - 2 5 6 " unix_socket_directories: ’ / v a r / r u n / p o s t g r e s q l / . ’ tags: nofailover: f a l s e noloadbalance: f a l s e clonefrom: f a l s e nosync: f a l s e Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The grid 32 / 63
file patroni.service [Unit] Description=Runners to orchestrate a high-availability PostgreSQL After=syslog.target network.target [Service] Type=simple User=postgres Group=postgres # Read in configuration file if it exists, otherwise proceed EnvironmentFile=-/etc/patroni_env.conf WorkingDirectory=/var/lib/pgsql # Start the patroni process ExecStart=/bin/patroni /etc/patroni/patroni.yml Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The grid 33 / 63
reload from patroni.yml ExecReload=/bin/kill -s HUP $MAINPID # only kill the patroni process, not it’s children, so it will gracefully stop postgres KillMode=process # Give a reasonable amount of time for the server to start up/shut down TimeoutSec=30 # Do not restart the service if it crashes, we want to manually inspect database on failure Restart=no [Install] WantedBy=multi-user.target Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The grid 34 / 63
https://geektyrant.com/news/the-history-of-the-tron-lightcycle-infographic Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The light cycle maze 38 / 63
servers Create the GCP bucket Create a new service account grant access to the GCP bucket Generate and save the service account’s access key in json format Configure pgBackRest for using the GCP bucket Configure patroni to use pgBackRest Run the pgBackRest first backup Profit Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The light cycle maze 40 / 63
/etc/pgbackrest.conf [global] repo1-type=gcs repo1-path=/repo repo1-gcs-bucket=pg_backup-grongo-571 repo1-gcs-key=/etc/gcp/gcp_key.json repo1-retention-full=1 log-level-console=info log-level-file=info backup-standby=y [flynn] # No pg1-host setting for the local instance pg1-path=/var/lib/pgsql/data/postgresql14 pg1-port=5432 pg1-user=postgres pg2-path=/var/lib/pgsql/data/postgresql14 pg2-port=5432 pg2-user=postgres Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The light cycle maze 41 / 63
password authentication it may be necessary to configure the .pgpass file in the PostgreSQL data directory. patroni-0:5432:*:postgres:SECRET patroni-0:5432:*:replicator:SUPER_SECRET patroni-0:5432:*:rewind_user:VERY_SECRET patroni-1:5432:*:postgres:SECRET patroni-1:5432:*:replicator:SUPER_SECRET patroni-1:5432:*:rewind_user:VERY_SECRET patroni-2:5432:*:postgres:SECRET patroni-2:5432:*:replicator:SUPER_SECRET patroni-2:5432:*:rewind_user:VERY_SECRET Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The light cycle maze 43 / 63
it the file gcp key.json downloaded from the GCP console. The directory and file must be accessible by the user running pgbackrest. { "type": "service_account", "project_id": "XXXXXXXXXXXXX", "private_key_id": "XXXXXXXXXXXXX", "private_key": "-----BEGIN PRIVATE KEY----- XXXXXXXXXXXXXXXXXXXX -----END PRIVATE KEY----- ", "client_email": "XXXXXXXXXXXXX", "client_id": "XXXXXXXXXXXXX", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/XXXXXXXXXXXXXXX" } Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The light cycle maze 44 / 63
## add the following lines under the parameters key postgresql : parameters : archive_command : pgbackrest --stanza=flynn archive -push %p After saving the data in the DCS patroni should reload the nodes in order to apply the new settings. Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest The light cycle maze 45 / 63
quella cosa che andava fatta prima. Translation: the backup is something to do before (the disaster strikes). Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest End of line 50 / 63
Install PostgreSQL and patroni Configure patroni to bootstrap and clone from pgBackRest Start patroni Profit Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest End of line 51 / 63
/etc/patroni/boot pgbackrest.sh #!/ usr/bin/env bash while getopts ": -:" optchar; do [[ "${optchar }" == "-" ]] || continue case "${OPTARG }" in datadir =* ) DATA_DIR=${OPTARG #*=} ;; scope =* ) SCOPE=${OPTARG #*=} ;; esac done /usr/bin/pgbackrest --stanza=$SCOPE --link -all restore Make the file executable Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest End of line 53 / 63
r u e use_slots: f a l s e parameters: wal_level: ’ r e p l i c a ’ archive_mode: ’ o n ’ archive_command: ’ p g b a c k r e s t - - s t a n z a = f l y n n a r c h i v e - p u s h % p ’ unix_socket_directories: ’ / v a r / r u n / p o s t g r e s q l / . ’ recovery_conf: recovery_target_timeline: l a t e s t restore_command: / u s r / b i n / p g b a c k r e s t - - s t a n z a = f l y n n a r c h i v e - g e t % f " % p " method: p g b a c k r e s t pgbackrest: command: / e t c / p a t r o n i / b o o t _ p g b a c k r e s t . s h keep_existing_recovery_conf: F a l s e recovery_conf: recovery_target_timeline: l a t e s t restore_command: / u s r / b i n / p g b a c k r e s t - - s t a n z a = f l y n n a r c h i v e - g e t % f " % p " Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest End of line 54 / 63
command: / u s r / b i n / p g b a c k r e s t - - s t a n z a = f l y n n r e s t o r e - - d e l t a - - l i n k - a l l keep_data: T r u e no_params: T r u e recovery_conf: recovery_target_timeline: l a t e s t restore_command: / u s r / b i n / p g b a c k r e s t - - s t a n z a = f l y n n a r c h i v e - g e t % f " % p " parameters: wal_level: ’ r e p l i c a ’ archive_mode: ’ o n ’ archive_command: ’ p g b a c k r e s t - - s t a n z a = f l y n n a r c h i v e - p u s h % p ’ unix_socket_directories: ’ / v a r / r u n / p o s t g r e s q l / . ’ ..... Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest End of line 55 / 63
/var/lib/pgsql/data/ postgresql14 chown postgres:postgres /var/lib/pgsql/data/ postgresql14 chmod 0700 /var/lib/pgsql/data/ postgresql14 Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest End of line 56 / 63
source https://disney.fandom.com/wiki/Tron (character) Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest I fight for the users 59 / 63
on github. https://github.com/the4thdoctor/patroni-pgbackrest-demo Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest I fight for the users 60 / 63
DBA to change their point of view Patroni doesn’t implement the DR but pgBackRest does it! This example is missing a lot of pieces (security, connection routing...) Using tools like Puppet or Ansible is a very,very,very,very,very good idea Always RTFM! Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest I fight for the users 61 / 63
Campoli PostgreSQL Europe 4th May 2024 Federico Campoli (PostgreSQL Europe) Protecting your data with Patroni and pgBackRest I fight for the users 63 / 63