Basic postgresql set up
Architecture
Machine | Ip Address | Role |
---|---|---|
postgres1 | 10.1.0.101 | Postgres, Patroni, HAProxy, Etcd |
postgres2 | 10.1.0.102 | Postgres, Patroni |
postgres3 | 10.1.0.103 | Postgres, Patroni |
Install etcd:
sudo mkdir -p /db/etcdsudo chown -R postgres:postgres /db/etcd
ETCD_VER=v3.3.18GOOGLE_URL=https://storage.googleapis.com/etcdDOWNLOAD_URL=${GOOGLE_URL}curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o etcd-${ETCD_VER}-linux-amd64.tar.gztar xzvf etcd-${ETCD_VER}-linux-amd64.tar.gzsudo cp etcd-${ETCD_VER}-linux-amd64/etcd* /usr/local/binrm -rf etcd-${ETCD_VER}-linux-amd64.tar.gz etcd-${ETCD_VER}-linux-amd64/
Install packages:
-
Install
postgresql-15
,patroni
,etcd
on all nodes:Terminal window sudo apt install dirmngr ca-certificates software-properties-common apt-transport-https lsb-release curl -ycurl -fSsL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /usr/share/keyrings/postgresql.gpg > /dev/nullecho deb [arch=amd64,arm64,ppc64el signed-by=/usr/share/keyrings/postgresql.gpg] http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main | sudo tee /etc/apt/sources.list.d/postgresql.listsudo apt update -ysudo apt install -y postgresql-client-15 postgresql-15sudo systemctl stop postgresqlsudo apt install -y python3-pip python3-testresources python3-psycopg2 net-toolssudo pip3 install --upgrade setuptoolssudo pip3 install patroni python-etcd -
(Optional) Install haproxy on
haproxy
node:Terminal window sudo apt install net-toolssudo apt -y install haproxy
Configuring:
Etcd on node postgres1
ETCD_NAME=postgres1ETCD_INITIAL_CLUSTER="postgres1=http://10.1.0.101:2380,postgres2=http://10.1.0.102:2380,postgres3=http://10.1.0.103:2380"ETCD_INITIAL_CLUSTER_STATE="new"ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.1.0.101:2380"ETCD_LISTEN_PEER_URLS="http://10.1.0.101:2380"ETCD_LISTEN_CLIENT_URLS="http://localhost:2379,http://10.1.0.101:2379"ETCD_ADVERTISE_CLIENT_URLS="http://10.1.0.101:2379"
- Start the
etcd
service to apply the changes on nodepostgres1
sudo systemctl enable --now etcdsudo systemctl start etcdsudo systemctl status etcd
- Check the etcd cluster members on node
postgres1
sudo etcdctl member list
Etcd on node postgres2
ETCD_NAME=postgres2ETCD_INITIAL_CLUSTER="postgres1=http://10.1.0.101:2380,postgres2=http://10.1.0.102:2380,postgres3=http://10.1.0.103:2380"ETCD_INITIAL_CLUSTER_STATE="new"ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.1.0.102:2380"ETCD_LISTEN_PEER_URLS="http://10.1.0.102:2380"ETCD_LISTEN_CLIENT_URLS="http://localhost:2379,http://10.1.0.102:2379"ETCD_ADVERTISE_CLIENT_URLS="http://10.1.0.102:2379"
name: postgres1data-dir: /db/etcdinitial-advertise-peer-urls: http://10.1.0.101:2380listen-peer-urls: http://10.1.0.101:2380listen-client-urls: http://10.1.0.101:2379advertise-client-urls: http://10.1.0.101:2379initial-cluster: "postgres1=http://10.1.0.101:2380,postgres2=http://10.1.0.102:2380,postgres3=http://10.1.0.103:2380"
name: postgres2data-dir: /db/etcdinitial-advertise-peer-urls: http://10.1.0.102:2380listen-peer-urls: http://10.1.0.102:2380listen-client-urls: http://10.1.0.102:2379advertise-client-urls: http://10.1.0.102:2379initial-cluster: "postgres1=http://10.1.0.101:2380,postgres2=http://10.1.0.102:2380,postgres3=http://10.1.0.103:2380"
name: postgres3data-dir: /db/etcdinitial-advertise-peer-urls: http://10.1.0.103:2380listen-peer-urls: http://10.1.0.103:2380listen-client-urls: http://10.1.0.103:2379advertise-client-urls: http://10.1.0.103:2379initial-cluster: "postgres1=http://10.1.0.101:2380,postgres2=http://10.1.0.102:2380,postgres3=http://10.1.0.103:2380"
Etcd on node postgres3
ETCD_NAME=postgres3ETCD_INITIAL_CLUSTER="postgres1=http://10.1.0.101:2380,postgres2=http://10.1.0.102:2380,postgres3=http://10.1.0.103:2380"ETCD_INITIAL_CLUSTER_STATE="new"ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.1.0.103:2380"ETCD_LISTEN_PEER_URLS="http://10.1.0.103:2380"ETCD_LISTEN_CLIENT_URLS="http://localhost:2379,http://10.1.0.103:2379"ETCD_ADVERTISE_CLIENT_URLS="http://10.1.0.103:2379"
Patroni on node postgres1
scope: postgresname: postgres1
restapi: listen: 10.1.0.101:8008 connect_address: 10.1.0.101:8008
etcd: host: 10.1.0.101:2379, 10.1.0.102:2379, 10.1.0.103:2379
bootstrap: dcs: ttl: 30 loop_wait: 10 retry_timeout: 10 maximum_lag_on_failover: 1048576 postgresql: use_pg_rewind: true use_slots: true parameters:
initdb: - encoding: UTF8 - data-checksums
pg_hba: - host replication replicator 127.0.0.1/32 md5 - host replication replicator 10.1.0.101/0 md5 - host replication replicator 10.1.0.102/0 md5 - host replication replicator 10.1.0.103/0 md5 - host all all 0.0.0.0/0 md5
users: admin: password: admin options: - createrole - createdb
postgresql: listen: 10.1.0.101:5432 connect_address: 10.1.0.101:5432 data_dir: /var/lib/postgresql/15/main bin_dir: /usr/lib/postgresql/15/bin pgpass: /tmp/pgpass authentication: replication: username: replicator password: replicator superuser: username: postgres password: postgres parameters: unix_socket_directories: '.'
tags: nofailover: false noloadbalance: false clonefrom: false nosync: false
sudo mkdir -p /data/patronisudo chown postgres:postgres /data/patronisudo chmod 700 /data/patroni
Patroni on node postgres2
scope: postgresname: postgres2
restapi: listen: 10.1.0.102:8008 connect_address: 10.1.0.102:8008
etcd: host: 10.1.0.101:2379, 10.1.0.102:2379, 10.1.0.103:2379
bootstrap: dcs: ttl: 30 loop_wait: 10 retry_timeout: 10 maximum_lag_on_failover: 1048576 postgresql: use_pg_rewind: true use_slots: true parameters:
initdb: - encoding: UTF8 - data-checksums
pg_hba: - host replication replicator 127.0.0.1/32 md5 - host replication replicator 10.1.0.101/0 md5 - host replication replicator 10.1.0.102/0 md5 - host replication replicator 10.1.0.103/0 md5 - host all all 0.0.0.0/0 md5
users: admin: password: admin options: - createrole - createdb
postgresql: listen: 10.1.0.102:5432 connect_address: 10.1.0.102:5432 data_dir: /var/lib/postgresql/15/main bin_dir: /usr/lib/postgresql/15/bin pgpass: /tmp/pgpass authentication: replication: username: replicator password: bae0-a5db-4068-ac4 superuser: username: postgres password: 31db-20f4-48d2-8b4 parameters: unix_socket_directories: '.'
tags: nofailover: false noloadbalance: false clonefrom: false nosync: false
[Unit]Description=High availability PostgreSQL ClusterAfter=syslog.target network.target
[Service]Type=simpleUser=postgresGroup=postgresExecStart=/usr/local/bin/patroni /etc/patroni.ymlKillMode=processTimeoutSec=30Restart=no
[Install]WantedBy=multi-user.targ
sudo systemctl start patronisudo systemctl status patroni
- Config HAProxy on node haproxy:
global
maxconn 100 log 127.0.0.1 local2
defaults log global mode tcp retries 2 timeout client 30m timeout connect 4s timeout server 30m timeout check 5s
listen stats mode http bind *:7000 stats enable stats uri /
listen postgres bind *:5000 option httpchk http-check expect status 200 default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions server postgres1 10.1.0.101:5432 maxconn 100 check port 8008 server postgres2 10.1.0.102:5432 maxconn 100 check port 8008 server postgres3 10.1.0.103:5432 maxconn 100 check port 8008
listen postgres-replica bind *:5001 option httpchk GET /replica http-check expect status 200 default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions server postgres1 10.1.0.101:5432 maxconn 100 check port 8008 server postgres2 10.1.0.102:5432 maxconn 100 check port 8008 server postgres3 10.1.0.103:5432 maxconn 100 check port 8008
sudo systemctl restart haproxy
- Test
patronictl -c /etc/patroni.yml list
Pooling connection with pgBouncer
COPY (SELECT '"' || rolname || '" "' ||coalesce(rolpassword, '') || '"'FROM pg_authid)TO '/tmp/userlist.txt';
- Install
sudo apt install -y pgbouncer
[databases]* = host=10.1.0.101 port=5432
[pgbouncer]listen_addr = *listen_port = 6432auth_type = md5admin_users = postgresauth_file = /etc/pgbouncer/userlist.txtmax_client_conn = 1000default_pool_size = 25reserve_pool_size = 5
Migration guide:
- First install all necessary packages by following the above steps
- Mount the stackgres data disk to the node
sudo rm -rf /var/lib/postgresql/15/mainsudo mount /dev/sdb /var/lib/postgresql/15sudo chown -R postgres:postgres /var/lib/postgresql/15sudo mv /var/lib/postgresql/15/data /var/lib/postgresql/15/mainsudo chmod 700 /var/lib/postgresql/15/main