
Install Postges trên tất cả các node
Tạo các user trên các nodesu postgres
/opt/postgres/bin/psql
postgres=# CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'x0hDfZv27';
postgres=# CREATE USER postgres WITH SUPERUSER ENCRYPTED PASSWORD 'njk16uAeFNl';
Install watchdogsudo vi /etc/watchdog.conf
## active dòng này lên, bỏ comment đi:
watchdog-device = /dev/watchdog
## thực hiện chuỗi lệnh bên dưới để active software watchdog
sudo mknod /dev/watchdog c 10 130
cat <<EOF >/etc/modules-load.d/softdog.conf
softdog
EOF
sudo modprobe softdog
sudo chown postgres /dev/watchdog
systemctl restart watchdog
Install etcd
apt install etcd -y
apt install etcd-server etcd-client -y
Cấu hình /etc/default/etcd
trên 3 node
ETCD_NAME="NODE01"
ETCD_DATA_DIR="/var/lib/etcd/node1"
ETCD_LISTEN_PEER_URLS="http://10.10.2.10:2380"
ETCD_LISTEN_CLIENT_URLS="http://10.10.2.10:2379,http://127.0.0.1:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.10.2.10:2380,http://127.0.0.1:2380"
ETCD_INITIAL_CLUSTER="node1=http://10.10.2.10:2380,node2=http://10.10.2.11:2380,node2=http://10.10.2.12:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-pgsql"
ETCD_ADVERTISE_CLIENT_URLS="http://10.10.2.10:2379"
ETCD_ENABLE_V2="true"
ETCD_NAME="NODE02"
ETCD_DATA_DIR="/var/lib/etcd/node2"
ETCD_LISTEN_PEER_URLS="http://10.10.2.11:2380"
ETCD_LISTEN_CLIENT_URLS="http://10.10.2.11:2379,http://127.0.0.1:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.10.2.11:2380,http://127.0.0.1:2380"
ETCD_INITIAL_CLUSTER="node1=http://10.10.2.10:2380,node2=http://10.10.2.11:2380,node2=http://10.10.2.12:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-pgsql"
ETCD_ADVERTISE_CLIENT_URLS="http://10.10.2.11:2379"
ETCD_ENABLE_V2="true"
ETCD_NAME="NODE03"
ETCD_DATA_DIR="/var/lib/etcd/node3"
ETCD_LISTEN_PEER_URLS="http://10.10.2.12:2380"
ETCD_LISTEN_CLIENT_URLS="http://10.10.2.12:2379,http://127.0.0.1:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.10.2.12:2380,http://127.0.0.1:2380"
ETCD_INITIAL_CLUSTER="node1=http://10.10.2.10:2380,node2=http://10.10.2.11:2380,node2=http://10.10.2.12:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-pgsql"
ETCD_ADVERTISE_CLIENT_URLS="http://10.10.2.12:2379"
ETCD_ENABLE_V2="true"
Install patroniapt install patroni
Trên node01mkdir -p /etc/patroni
nano /etc/patroni/patroni.yml
scope: postgres
namespace: /db/
name: pg01
restapi:
listen: 10.10.2.10:8008
connect_address: 10.10.2.10:8008
etcd:
host: 10.10.2.10:2379
bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576
postgresql:
use_pg_rewind: true
parameters:
max_connections: 1000
shared_buffers: 4GB
effective_cache_size: 12GB
maintenance_work_mem: 2GB
checkpoint_completion_target: 0.9
wal_buffers: 16MB
default_statistics_target: 500
random_page_cost: 1.1
effective_io_concurrency: 200
work_mem: 524kB
min_wal_size: 4GB
max_wal_size: 8GB
max_worker_processes: 8
max_parallel_workers_per_gather: 4
max_parallel_workers: 8
dynamic_shared_memory_type: mmap
log_statement: 'all'
log_duration: on
log_min_duration_statement: '100ms'
log_destination: 'csvlog'
logging_collector: 'on'
compute_query_id: 'on'
log_directory: '/opt/db/postgres/pglog/'
log_filename: 'postgresql-%Y-%m-%d_%H.log'
log_truncate_on_rotation: on
log_rotation_age: 1d
log_rotation_size: 100MB
log_timezone: 'Asia/Saigon'
datestyle: 'iso, mdy'
timezone: 'Asia/Saigon'
lc_messages: 'en_US.UTF-8'
lc_monetary: 'en_US.UTF-8'
lc_numeric: 'en_US.UTF-8'
lc_time: 'en_US.UTF-8'
default_text_search_config: 'pg_catalog.english'
shared_preload_libraries: pg_stat_statements
pg_stat_statements.track: all
initdb:
- encoding: UTF8
- data-checksums
- auth-host: md5
- auth-local: trust
#pg_hba:
#- host replication replicator 127.0.0.1/32 md5
#- host replication replicator 2.2.2.46/32 trust
#- host replication replicator 2.2.2.115/32 trust
#- host replication replicador all md5
#- host replication replicador 0.0.0.0/0 md5
#- host all postgres 127.0.0.1/32 trust
#- host all postgres 2.2.2.46/32 trust
#- host all postgres 2.2.2.115/32 trust
#- host all postgres 0.0.0.0/0 md5
#- host all all 127.0.0.1/32 trust
#- host all all 0.0.0.0/0 md5
users:
admin:
password: admin
options:
- createrole
- createdb
postgresql:
listen: 0.0.0.0:5432
connect_address: 10.10.2.10:5432
data_dir: /opt/db/postgres/pgdata
bin_dir: /opt/db/postgres/bin
pgpass: /tmp/pgpass
authentication:
replication:
username: replicator
password: x0hDfZv27
superuser:
username: postgres
password: njk16uAeFNl
parameters:
unix_socket_directories: '.'
watchdog:
mode: required
device: /dev/watchdog
safety_margin: 5
tags:
nofailover: false
noloadbalance: false
clonefrom: false
nosync: false
Trên node02mkdir -p /etc/patroni
nano /etc/patroni/patroni.yml
scope: postgres
namespace: /db/
name: pg02
restapi:
listen: 10.10.2.11:8008
connect_address: 10.10.2.11:8008
etcd:
host: 10.10.2.11:2379
bootstrap:
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 10
maximum_lag_on_failover: 1048576
postgresql:
use_pg_rewind: true
parameters:
max_connections: 1000
shared_buffers: 4GB
effective_cache_size: 12GB
maintenance_work_mem: 2GB
checkpoint_completion_target: 0.9
wal_buffers: 16MB
default_statistics_target: 500
random_page_cost: 1.1
effective_io_concurrency: 200
work_mem: 524kB
min_wal_size: 4GB
max_wal_size: 8GB
max_worker_processes: 8
max_parallel_workers_per_gather: 4
max_parallel_workers: 8
dynamic_shared_memory_type: mmap
log_statement: 'all'
log_duration: on
log_min_duration_statement: '100ms'
log_destination: 'csvlog'
logging_collector: 'on'
compute_query_id: 'on'
log_directory: '/opt/db/postgres/pglog/'
log_filename: 'postgresql-%Y-%m-%d_%H.log'
log_truncate_on_rotation: on
log_rotation_age: 1d
log_rotation_size: 100MB
log_timezone: 'Asia/Saigon'
datestyle: 'iso, mdy'
timezone: 'Asia/Saigon'
lc_messages: 'en_US.UTF-8'
lc_monetary: 'en_US.UTF-8'
lc_numeric: 'en_US.UTF-8'
lc_time: 'en_US.UTF-8'
default_text_search_config: 'pg_catalog.english'
shared_preload_libraries: pg_stat_statements
pg_stat_statements.track: all
initdb:
- encoding: UTF8
- data-checksums
- auth-host: md5
- auth-local: trust
#pg_hba:
#- host replication replicator 127.0.0.1/32 md5
#- host replication replicator 2.2.2.46/32 trust
#- host replication replicator 2.2.2.115/32 trust
#- host replication replicador all md5
#- host replication replicador 0.0.0.0/0 md5
#- host all postgres 127.0.0.1/32 trust
#- host all postgres 2.2.2.46/32 trust
#- host all postgres 2.2.2.115/32 trust
#- host all postgres 0.0.0.0/0 md5
#- host all all 127.0.0.1/32 trust
#- host all all 0.0.0.0/0 md5
users:
admin:
password: admin
options:
- createrole
- createdb
postgresql:
listen: 0.0.0.0:5432
connect_address: 10.10.2.11:5432
data_dir: /opt/db/postgres/pgdata
bin_dir: /opt/db/postgres/bin
pgpass: /tmp/pgpass
authentication:
replication:
username: replicator
password: x0hDfZv27
superuser:
username: postgres
password: njk16uAeFNl
parameters:
unix_socket_directories: '.'
watchdog:
mode: required
device: /dev/watchdog
safety_margin: 5
tags:
nofailover: false
noloadbalance: false
clonefrom: false
nosync: false
mkdir -p /dev/data/patroni
chown postgres:postgres /dev/data/patroni
chmod 700 /dev/data/patroni
Create service patroni
cat <<EOF >/etc/systemd/system/patroni.service
[Unit]
Description=Runners to orchestrate a high-availability PostgreSQL
After=syslog.target network.target
Wants=network-online.target
[Service]
Type=simple
User=postgres
Group=postgres
PermissionsStartOnly=true
ExecStart=/usr/local/bin/patroni /etc/patroni/patroni.yml
ExecReload=/bin/kill -HUP $MAINPID
LimitNOFILE=65536
KillMode=process
KillSignal=SIGINT
Restart=on-abnormal
KillMode=process
TimeoutSec=30
Restart=no
[Install]
WantedBy=multi-user.target
EOF
systemctl enable patroni --now
Install và config haproxy trên 2 nodesapt update
apt install haproxy -ynano /etc/haproxy/haproxy.conf
global
maxconn 100
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 PSQL_MASTER_5000_rw
bind *:5000
option httpchk
http-check expect status 200
default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
server postgresql_2.10_5432 10.10.2.10:5432 maxconn 800 check port 8008
server postgresql_2.11_5432 10.10.2.11:5432 maxconn 800 check port 8008
# Connections to port 5listen PSQL_MASTER_5001_ro
listen PSQL_5001_ro
bind *:5001
option httpchk
http-check expect !status 200
default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
server postgresql_2.45_5432 10.10.2.10:5432 maxconn 800 check port 8008
server postgresql_2.46_5432 10.10.2.11:5432 maxconn 800 check port 8008
systemctl start haproxy
systemctl status haproxy
Install và config keepalived trên 2 nodes apt update
apt install keepalived -ynano /etc/keepalived/keepalived.conf
NODE01
vrrp_script chk_haproxy {
script "/usr/bin/killall -0 haproxy"
interval 2
weight 2
}
vrrp_instance VI_1 {
interface eth0
virtual_router_id 51
state MASTER
priority 102
virtual_ipaddress {
10.10.2.15
}
track_script {
chk_haproxy
}
}
NODE02
vrrp_script chk_haproxy {
script "/usr/bin/killall -0 haproxy"
interval 2
weight 2
}
vrrp_instance VI_1 {
interface eth0
virtual_router_id 51
state BACKUP
priority 101
virtual_ipaddress {
10.10.2.15
}
track_script {
chk_haproxy
}
}
systemctl start keepalived
systemctl status keepalived
Kiểm tra hệ thống
etcdetcdctl member list
438941bcea951af5, started, node1, http://10.10.2.10:2380, http://
10.10.2.10
:2379, false
6e6ad8e4eb4ca5e6, started, node2, http://10.10.2.11
:2380, http://10.10.2.11
:2379, false
fa858d35ae3aabd4, started, node3, http://10.10.2.1
2:2380, http://10.10.2.1
2:2379, false
patronipatronictl -c /etc/patroni/patroni.yml list
+ Cluster: postgres (7432164371019840658) -----+-----+-----------+
| Member | Host | Role | State | TL | Lag in MB |
+-----------+------------+---------+-----------+-----+-----------+
| pg01 | 10.10.2.10 | Replica | streaming | 687 | 0 |
| pg02 | 10.10.2.11 | Leader | running | 687 | |
+-----------+------------+---------+-----------+-----+-----------+