datenbank:ha-postgresql-cluster
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
| datenbank:ha-postgresql-cluster [2026-05-12 17:55:18] – manfred | datenbank:ha-postgresql-cluster [2026-05-29 10:09:43] (aktuell) – [Tests] manfred | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| ====== HA-PostgreSQL-Cluster ====== | ====== HA-PostgreSQL-Cluster ====== | ||
| + | |||
| + | siehe auch: **[[:: | ||
| Zeile 6: | Zeile 8: | ||
| //Es soll ein hochverfügbarer PostgreSQL‑Cluster mit Patroni, EtcE, HAProxy und KeepaliveD auf drei Systemen installiert werden.// | //Es soll ein hochverfügbarer PostgreSQL‑Cluster mit Patroni, EtcE, HAProxy und KeepaliveD auf drei Systemen installiert werden.// | ||
| - | Wichtige Unterschiede zwischen diesem HA-PostgreSQL-Cluster mit 3 Systemen, gegenüber einem HA-PostgreSQL-Cluster mit 5 Systemen sind, dass hier alle Pakete auf allen 3 Systemen installiert werden müssen. Und weil PostgreSQL und HAProxy auf dem selben Host laufen, muß der Datenbank-Zugriff über den Cluster-Zugang (HAProxy) auf einen anderen Port laufen. In diesem Fall laufen die PostgreSQL-Instanzen | + | Wichtige Unterschiede zwischen diesem HA-PostgreSQL-Cluster mit 3 Systemen, gegenüber einem HA-PostgreSQL-Cluster mit 5 Systemen sind, dass hier alle Pakete auf allen 3 Systemen installiert werden müssen. Und weil PostgreSQL und HAProxy auf dem selben Host laufen, muß der Datenbank-Zugriff über den Cluster-Zugang (HAProxy) auf einen anderen Port laufen. |
| + | In diesem Fall laufen die PostgreSQL-Instanzen | ||
| In einem HA-PostgreSQL-Cluster mit 5 Systemen laufen EtcE, HAProxy und KeepaliveD auf 2 separate Systeme und dann können PostgreSQL und HAProxy auf dem gleichen Port laufen. | In einem HA-PostgreSQL-Cluster mit 5 Systemen laufen EtcE, HAProxy und KeepaliveD auf 2 separate Systeme und dann können PostgreSQL und HAProxy auf dem gleichen Port laufen. | ||
| Zeile 18: | Zeile 21: | ||
| > apt install vim screen mc csync2 links python3 python3-psycopg2 jq curl wget net-tools etcd-server etcd-client haproxy keepalived postgresql postgresql-contrib patroni | > apt install vim screen mc csync2 links python3 python3-psycopg2 jq curl wget net-tools etcd-server etcd-client haproxy keepalived postgresql postgresql-contrib patroni | ||
| > echo " | > echo " | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== PG-DataDir mit ZFS ==== | ||
| + | |||
| + | <code bash DataDir im RAID-1> | ||
| + | > apt install zfsutils-linux | ||
| + | |||
| + | > zpool create -m / | ||
| + | > zpool list | ||
| + | NAME | ||
| + | pg_datadir | ||
| + | |||
| + | > zpool status | ||
| + | pool: pg_datadir | ||
| + | | ||
| + | config: | ||
| + | |||
| + | NAME | ||
| + | pg_datadir | ||
| + | mirror-0 | ||
| + | nvme2n1 | ||
| + | nvme3n1 | ||
| + | |||
| + | errors: No known data errors | ||
| + | |||
| + | > zfs set compression=lz4 | ||
| + | > zfs set recordsize=16K | ||
| + | > zfs set logbias=latency | ||
| + | > zfs set atime=off | ||
| + | |||
| + | > mkdir -p / | ||
| + | > chown -R postgres: | ||
| + | > chmod 700 / | ||
| + | |||
| + | > mount | grep postgresql | ||
| + | |||
| + | > zfs get mountpoint, | ||
| + | NAME PROPERTY | ||
| + | pg_datadir | ||
| + | pg_datadir | ||
| + | pg_datadir | ||
| + | pg_datadir | ||
| + | pg_datadir | ||
| + | |||
| + | > df -h | ||
| + | Filesystem | ||
| + | ... | ||
| + | pg_datadir | ||
| </ | </ | ||
| Zeile 28: | Zeile 80: | ||
| group Loadbalancer #group name, we can have multiple groups | group Loadbalancer #group name, we can have multiple groups | ||
| { | { | ||
| - | host pg-knoten-01; #master server | + | host FRA2A-MEDOS04; #master server |
| - | host pg-knoten-02; #slave server | + | host FRA2B-MEDOS04; #slave server |
| - | host pg-knoten-03; #slave server | + | host FRA2C-MEDOS04; #slave server |
| key / | key / | ||
| Zeile 137: | Zeile 189: | ||
| <code text Starten> | <code text Starten> | ||
| - | systemctl restart etcd | + | > systemctl restart etcd |
| - | systemctl enable etcd | + | > systemctl enable etcd |
| </ | </ | ||
| Zeile 151: | Zeile 203: | ||
| === Hinweis === | === Hinweis === | ||
| - | **//Solange der Cluster unhealthy ist, sind Verwaltungsoperationen wie etcdctl member add absichtlich verboten.// | + | **//Solange der Cluster unhealthy ist, sind Verwaltungsoperationen wie '' |
| <code bash> | <code bash> | ||
| Zeile 239: | Zeile 291: | ||
| frontend postgres_write | frontend postgres_write | ||
| #bind *:5432 | #bind *:5432 | ||
| - | bind *:5433 | + | bind *:5433 # Port zum schreiben |
| default_backend pg_leader | default_backend pg_leader | ||
| Zeile 255: | Zeile 307: | ||
| # LESEZUGRIFFE (alle, lastverteilung) | # LESEZUGRIFFE (alle, lastverteilung) | ||
| # ============================ | # ============================ | ||
| - | # [~]# curl -s " | + | # [~]# curl -s " |
| # pg1 UP -1 | # pg1 UP -1 | ||
| # pg2 DOWN -1 | # pg2 DOWN -1 | ||
| # pg3 DOWN -1 | # pg3 DOWN -1 | ||
| # BACKEND UP -1 | # BACKEND UP -1 | ||
| - | # pg1 UP -1 | + | # pg1 DOWN -1 |
| # pg2 UP -1 | # pg2 UP -1 | ||
| # pg3 UP -1 | # pg3 UP -1 | ||
| # BACKEND UP -1 | # BACKEND UP -1 | ||
| frontend postgres_read | frontend postgres_read | ||
| - | bind *:6543 | + | bind *:5443 # Port zum lesen |
| - | default_backend pg_replica | + | # |
| - | + | # | |
| - | backend pg_replica | + | # Wenn mindestens eine Replica gesund ist → Replicas |
| - | mode tcp | + | use_backend pg_replicas if { nbsrv(pg_replicas) gt 0 } |
| - | option httpchk | + | # |
| - | balance leastconn | + | # Andernfalls automatisch zum Leader |
| - | http-check send meth GET uri /liveness ver HTTP/1.1 hdr Host localhost | + | |
| - | http-check expect status 200 | + | |
| - | default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions | + | |
| - | server pg1 pg-knoten-01: | + | |
| - | server pg2 pg-knoten-02: | + | |
| - | server pg3 pg-knoten-03: | + | |
| - | </ | + | |
| - | + | ||
| - | <hidden / | + | |
| - | <code text / | + | |
| - | global | + | |
| - | log /dev/log local0 | + | |
| - | maxconn 5000 | + | |
| - | stats socket / | + | |
| - | + | ||
| - | defaults | + | |
| - | mode tcp | + | |
| - | timeout connect 5s | + | |
| - | timeout client | + | |
| - | timeout server | + | |
| - | + | ||
| - | + | ||
| - | listen stats | + | |
| - | bind 0.0.0.0: | + | |
| - | #bind 127.0.0.1: | + | |
| - | mode http | + | |
| - | stats enable | + | |
| - | stats uri /stats | + | |
| - | stats refresh 10s | + | |
| - | stats auth admin: | + | |
| - | + | ||
| - | frontend postgresql | + | |
| - | # Weil HAProxy und PostgreSQL auf dem selben host laufen, | + | |
| - | # muß der HAProxy einen anderen | + | |
| - | #bind *:5432 | + | |
| - | bind *:5433 | + | |
| - | default_backend | + | |
| - | + | ||
| - | # HAProxy überprüft nicht den PostgreSQL-Port, | + | |
| - | # sondern den Patroni-Port! | + | |
| - | # Es genügt also nicht, die DB zu starten | + | |
| - | # es muß Patroni laufen, der startet dann PostgreSQL. | + | |
| - | # [~]# curl -s " | + | |
| - | # pg1 UP 909 | + | |
| - | # pg2 UP 899 | + | |
| - | # pg3 UP 1211 | + | |
| - | # BACKEND UP 902 | + | |
| - | backend pg_patroni_knoten | + | |
| - | http-check send meth GET /liveness | + | |
| - | http-check expect status 200 | + | |
| - | server pg1 pg-knoten-01: | + | |
| - | server pg2 pg-knoten-02: | + | |
| - | server pg3 pg-knoten-03: | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <hidden / | + | |
| - | <code text / | + | |
| - | global | + | |
| - | log /dev/log local0 | + | |
| - | maxconn 5000 | + | |
| - | stats socket / | + | |
| - | + | ||
| - | defaults | + | |
| - | mode tcp | + | |
| - | timeout connect 5s | + | |
| - | timeout client | + | |
| - | timeout server | + | |
| - | timeout check 5s | + | |
| - | log global | + | |
| - | option tcplog | + | |
| - | retries 3 | + | |
| - | + | ||
| - | + | ||
| - | listen stats | + | |
| - | bind 0.0.0.0: | + | |
| - | mode http | + | |
| - | stats enable | + | |
| - | stats uri /stats | + | |
| - | stats refresh 10s | + | |
| - | stats auth admin: | + | |
| - | + | ||
| - | # ============================ | + | |
| - | # SCHREIBZUGRIFFE (nur Leader/Primary) | + | |
| - | # ============================ | + | |
| - | frontend postgres_write | + | |
| - | #bind *:5432 | + | |
| - | bind *:5433 | + | |
| default_backend pg_leader | default_backend pg_leader | ||
| - | backend | + | backend |
| mode tcp | mode tcp | ||
| option httpchk | option httpchk | ||
| - | http-check send meth GET uri /primary | + | balance leastconn # |
| + | http-check send meth GET uri /replica | ||
| http-check expect status 200 | http-check expect status 200 | ||
| - | default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions | + | default-server inter 3s fall 3 rise 2 |
| - | server pg1 pg-knoten-01: | + | |
| - | server pg2 pg-knoten-02: | + | |
| - | server pg3 pg-knoten-03: | + | |
| - | + | ||
| - | # ============================ | + | |
| - | # LESEZUGRIFFE (alle, lastverteilung) | + | |
| - | # ============================ | + | |
| - | # [~]# curl -s " | + | |
| - | # pg1 UP -1 | + | |
| - | # pg2 DOWN -1 | + | |
| - | # pg3 DOWN -1 | + | |
| - | # BACKEND UP -1 | + | |
| - | # pg1 UP -1 | + | |
| - | # pg2 UP -1 | + | |
| - | # pg3 UP -1 | + | |
| - | # BACKEND UP -1 | + | |
| - | frontend postgres_read | + | |
| - | bind *:6543 | + | |
| - | default_backend pg_replica | + | |
| - | + | ||
| - | backend pg_replica | + | |
| - | mode tcp | + | |
| - | option httpchk | + | |
| - | balance leastconn | + | |
| - | http-check send meth GET uri /liveness ver HTTP/1.1 hdr Host localhost | + | |
| - | http-check expect status 200 | + | |
| - | default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions | + | |
| - | server pg1 pg-knoten-01: | + | |
| - | server pg2 pg-knoten-02: | + | |
| - | server pg3 pg-knoten-03: | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <hidden / | + | |
| - | <code text / | + | |
| - | global | + | |
| - | log /dev/log local0 | + | |
| - | maxconn 5000 | + | |
| - | stats socket / | + | |
| - | + | ||
| - | defaults | + | |
| - | mode tcp | + | |
| - | timeout connect 5s | + | |
| - | timeout client | + | |
| - | timeout server | + | |
| - | timeout check 5s | + | |
| - | log global | + | |
| - | option tcplog | + | |
| - | retries 3 | + | |
| - | + | ||
| - | + | ||
| - | listen stats | + | |
| - | bind 0.0.0.0: | + | |
| - | mode http | + | |
| - | stats enable | + | |
| - | stats uri /stats | + | |
| - | stats refresh 10s | + | |
| - | stats auth admin: | + | |
| - | + | ||
| - | # ============================ | + | |
| - | # SCHREIBZUGRIFFE (nur Leader/ | + | |
| - | # ============================ | + | |
| - | frontend postgres_write | + | |
| - | #bind *:5432 | + | |
| - | bind *:5433 | + | |
| - | default_backend pg_leader | + | |
| - | + | ||
| - | backend pg_leader | + | |
| - | mode tcp | + | |
| - | option httpchk | + | |
| - | http-check send meth GET uri /primary ver HTTP/1.1 hdr Host localhost | + | |
| - | http-check expect status 200 | + | |
| - | default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions | + | |
| - | server pg1 pg-knoten-01: | + | |
| - | server pg2 pg-knoten-02: | + | |
| - | server pg3 pg-knoten-03: | + | |
| - | + | ||
| - | # ============================ | + | |
| - | # LESEZUGRIFFE (nur Replicas, lastverteilung) | + | |
| - | # ============================ | + | |
| - | # [~]# curl -s " | + | |
| - | # pg1 UP -1 | + | |
| - | # pg2 DOWN -1 | + | |
| - | # pg3 DOWN -1 | + | |
| - | # BACKEND UP -1 | + | |
| - | # pg1 DOWN -1 | + | |
| - | # pg2 UP -1 | + | |
| - | # pg3 UP -1 | + | |
| - | # BACKEND UP -1 | + | |
| - | frontend postgres_read | + | |
| - | bind *:6543 | + | |
| - | default_backend pg_replica | + | |
| - | + | ||
| - | backend pg_replica | + | |
| - | mode tcp | + | |
| - | option httpchk | + | |
| - | balance leastconn | + | |
| - | http-check send meth GET uri /primary ver HTTP/1.1 hdr Host localhost | + | |
| - | http-check expect status 503 | + | |
| - | default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions | + | |
| server pg1 pg-knoten-01: | server pg1 pg-knoten-01: | ||
| server pg2 pg-knoten-02: | server pg2 pg-knoten-02: | ||
| server pg3 pg-knoten-03: | server pg3 pg-knoten-03: | ||
| </ | </ | ||
| - | </ | ||
| <code bash> | <code bash> | ||
| > service haproxy restart | > service haproxy restart | ||
| ... | ... | ||
| - | May 08 17: | + | May 08 17: |
| - | May 08 17: | + | May 08 17: |
| - | May 08 17: | + | May 08 17: |
| - | May 08 17: | + | May 08 17: |
| - | May 08 17: | + | May 08 17: |
| - | May 08 17: | + | May 08 17: |
| > ss -antp | grep -F LISTEN | grep -F haproxy | > ss -antp | grep -F LISTEN | grep -F haproxy | ||
| - | LISTEN | + | LISTEN |
| + | LISTEN | ||
| + | LISTEN | ||
| </ | </ | ||
| Zeile 562: | Zeile 428: | ||
| vrrp_no_swap | vrrp_no_swap | ||
| } | } | ||
| - | + | ||
| vrrp_script chk_dienst_vip { | vrrp_script chk_dienst_vip { | ||
| - | script "/ | + | |
| interval 2 | interval 2 | ||
| - | weight | + | weight |
| - | fall 2 | + | fall 2 |
| } | } | ||
| - | + | ||
| vrrp_instance VIP { | vrrp_instance VIP { | ||
| - | interface bond2 | + | |
| - | | + | |
| virtual_router_id 203 | virtual_router_id 203 | ||
| + | state BACKUP | ||
| priority 100 | priority 100 | ||
| + | #nopreempt | ||
| advert_int 1 | advert_int 1 | ||
| - | + | ||
| track_script { | track_script { | ||
| chk_dienst_vip | chk_dienst_vip | ||
| } | } | ||
| - | + | ||
| authentication { | authentication { | ||
| auth_type PASS | auth_type PASS | ||
| auth_pass RaBoo9as | auth_pass RaBoo9as | ||
| } | } | ||
| - | + | ||
| virtual_ipaddress { | virtual_ipaddress { | ||
| 10.145.43.30/ | 10.145.43.30/ | ||
| } | } | ||
| - | + | ||
| - | unicast_src_ip 10.145.43.31 | + | # |
| - | unicast_peer { | + | |
| - | # | + | |
| - | 10.145.43.32 | + | unicast_peer { |
| - | 10.145.43.33 | + | # |
| - | } | + | 10.145.43.32 |
| + | 10.145.43.33 | ||
| + | } | ||
| } | } | ||
| </ | </ | ||
| Zeile 606: | Zeile 476: | ||
| vrrp_no_swap | vrrp_no_swap | ||
| } | } | ||
| - | + | ||
| vrrp_script chk_dienst_vip { | vrrp_script chk_dienst_vip { | ||
| - | script "/ | + | |
| interval 2 | interval 2 | ||
| - | weight | + | weight |
| - | fall 2 | + | fall 2 |
| } | } | ||
| - | + | ||
| vrrp_instance VIP { | vrrp_instance VIP { | ||
| - | interface bond2 | + | |
| - | | + | |
| virtual_router_id 203 | virtual_router_id 203 | ||
| + | state BACKUP | ||
| priority 100 | priority 100 | ||
| + | #nopreempt | ||
| advert_int 1 | advert_int 1 | ||
| - | + | ||
| track_script { | track_script { | ||
| chk_dienst_vip | chk_dienst_vip | ||
| } | } | ||
| - | + | ||
| authentication { | authentication { | ||
| auth_type PASS | auth_type PASS | ||
| auth_pass RaBoo9as | auth_pass RaBoo9as | ||
| } | } | ||
| - | + | ||
| virtual_ipaddress { | virtual_ipaddress { | ||
| 10.145.43.30/ | 10.145.43.30/ | ||
| } | } | ||
| - | + | ||
| - | unicast_src_ip 10.145.43.32 | + | # |
| - | unicast_peer { | + | |
| - | 10.145.43.31 | + | |
| - | # | + | unicast_peer { |
| - | 10.145.43.33 | + | 10.145.43.31 |
| - | } | + | # |
| + | 10.145.43.33 | ||
| + | } | ||
| } | } | ||
| </ | </ | ||
| Zeile 650: | Zeile 524: | ||
| vrrp_no_swap | vrrp_no_swap | ||
| } | } | ||
| - | + | ||
| vrrp_script chk_dienst_vip { | vrrp_script chk_dienst_vip { | ||
| - | script "/ | + | |
| interval 2 | interval 2 | ||
| - | weight | + | weight |
| - | fall 2 | + | fall 2 |
| } | } | ||
| - | + | ||
| vrrp_instance VIP { | vrrp_instance VIP { | ||
| - | interface bond2 | + | |
| + | interface vlan203 | ||
| + | virtual_router_id 203 | ||
| state BACKUP | state BACKUP | ||
| - | virtual_router_id 203 | ||
| priority 100 | priority 100 | ||
| + | #nopreempt | ||
| advert_int 1 | advert_int 1 | ||
| - | + | ||
| track_script { | track_script { | ||
| chk_dienst_vip | chk_dienst_vip | ||
| } | } | ||
| - | + | ||
| authentication { | authentication { | ||
| auth_type PASS | auth_type PASS | ||
| auth_pass RaBoo9as | auth_pass RaBoo9as | ||
| } | } | ||
| - | + | ||
| virtual_ipaddress { | virtual_ipaddress { | ||
| 10.145.43.30/ | 10.145.43.30/ | ||
| } | } | ||
| - | |||
| - | unicast_src_ip 10.145.43.33 | ||
| - | unicast_peer { | ||
| - | 10.145.43.31 | ||
| - | 10.145.43.32 | ||
| - | # | ||
| - | } | ||
| - | } | ||
| - | </ | ||
| - | <file bash / | + | |
| - | #!/ | + | |
| - | + | ||
| - | # | + | |
| - | # Dieses Skript prüft den Zugriff auf die einzelnen DB-Knoten. | + | |
| - | # Es wird erst ein Fehler ausgegeben, wenn kein DB-Knoten mehr erreichbar ist. | + | |
| - | # | + | |
| - | + | ||
| - | ### Wenn PostgreSQL+Patroni nicht mit ETCD, HAProxy und KeepaliveD auf dem selben Host liegen | + | |
| - | # | + | |
| - | #do | + | |
| - | # echo " | + | |
| - | # | + | |
| - | + | ||
| - | ### Nur wenn PostgreSQL+Patroni, | + | |
| - | AUSGABE=" | + | |
| - | # Test | + | unicast_src_ip 10.145.43.33 |
| - | #echo " | + | |
| - | + | | |
| - | if [ x = " | + | |
| - | echo "CRIT: kein DB-Knoten ist erreichbar" | + | # |
| - | | + | |
| - | else | + | } |
| - | echo "OK: ${AUSGABE}" | tr -s ' | + | |
| - | exit 0 | + | |
| - | fi | + | |
| </ | </ | ||
| Zeile 720: | Zeile 569: | ||
| # | # | ||
| - | # Dieses Skript prüft | + | # Dieses Skript prüft, |
| - | # Es wird erst ein Fehler ausgegeben, wenn kein DB-Knoten mehr erreichbar ist. | + | |
| # | # | ||
| - | HA_PORT=" | + | # Prüfe, ob HAProxy läuft und erreichbar ist |
| - | SS_AUSGABE="$(ss -antp | grep -F LISTEN | grep -F " | + | HOST="127.0.0.1" |
| - | HA_AUSGABE=" | + | PORT=5433 |
| - | if [ x = "x${SS_AUSGABE}" ] ; then | + | # timeout wichtig, damit Keepalived nicht hängt |
| - | echo "CRIT: Port nicht offen" | + | timeout 1 bash -c "</ |
| - | | + | |
| + | if [ $? -eq 0 ]; then | ||
| + | exit 0 # OK → VIP behalten | ||
| else | else | ||
| - | if [ 3 -eq " | + | |
| - | echo " | + | |
| - | exit 0 | + | |
| - | else | + | |
| - | echo "CRIT: haproxy antwortet nicht richtig" | + | |
| - | exit 2 | + | |
| - | fi | + | |
| fi | fi | ||
| </ | </ | ||
| Zeile 749: | Zeile 593: | ||
| <code text VIP testen> | <code text VIP testen> | ||
| > ping 10.145.43.30 | > ping 10.145.43.30 | ||
| + | </ | ||
| + | |||
| + | |||
| + | === VRRP-Kommunikation === | ||
| + | |||
| + | <code bash> | ||
| + | > # tcpdump -i vlan203 proto 112 -n | grep -F 'vrid 203' | ||
| + | tcpdump: verbose output suppressed, use -v[v]... for full protocol decode | ||
| + | listening on vlan203, link-type EN10MB (Ethernet), snapshot length 262144 bytes | ||
| + | 12: | ||
| + | 12: | ||
| + | 12: | ||
| + | 12: | ||
| </ | </ | ||
| Zeile 763: | Zeile 620: | ||
| <code bash Netzwerkzugriffe erlauben> | <code bash Netzwerkzugriffe erlauben> | ||
| - | > echo " | + | > echo " |
| + | > echo " | ||
| + | > echo " | ||
| > echo " | > echo " | ||
| > echo " | > echo " | ||
| Zeile 913: | Zeile 772: | ||
| username: repl | username: repl | ||
| password: AejohTe6 | password: AejohTe6 | ||
| - | + | ||
| pg_hba: | pg_hba: | ||
| - | - host postgres dbcheck | + | - host replication all 0.0.0.0/ |
| - | - host postgres dbcheck | + | - host replication all ::/0 scram-sha-256 |
| - host all all 0.0.0.0/0 scram-sha-256 | - host all all 0.0.0.0/0 scram-sha-256 | ||
| - host all all ::/0 scram-sha-256 | - host all all ::/0 scram-sha-256 | ||
| Zeile 971: | Zeile 830: | ||
| username: repl | username: repl | ||
| password: AejohTe6 | password: AejohTe6 | ||
| - | + | ||
| pg_hba: | pg_hba: | ||
| - | - host postgres dbcheck | + | - host replication all 0.0.0.0/ |
| - | - host postgres dbcheck | + | - host replication all ::/0 scram-sha-256 |
| - host all all 0.0.0.0/0 scram-sha-256 | - host all all 0.0.0.0/0 scram-sha-256 | ||
| - host all all ::/0 scram-sha-256 | - host all all ::/0 scram-sha-256 | ||
| Zeile 1029: | Zeile 888: | ||
| username: repl | username: repl | ||
| password: AejohTe6 | password: AejohTe6 | ||
| - | + | ||
| pg_hba: | pg_hba: | ||
| - | - host postgres dbcheck | + | - host replication all 0.0.0.0/ |
| - | - host postgres dbcheck | + | - host replication all ::/0 scram-sha-256 |
| - host all all 0.0.0.0/0 scram-sha-256 | - host all all 0.0.0.0/0 scram-sha-256 | ||
| - host all all ::/0 scram-sha-256 | - host all all ::/0 scram-sha-256 | ||
| Zeile 1042: | Zeile 901: | ||
| > systemctl disable postgresql | > systemctl disable postgresql | ||
| > cp / | > cp / | ||
| + | > cp / | ||
| > mkdir / | > mkdir / | ||
| Zeile 1159: | Zeile 1019: | ||
| | Member | | Member | ||
| +--------------+--------------+---------+---------+----+-----------+ | +--------------+--------------+---------+---------+----+-----------+ | ||
| - | | pg-knoten-01 | pg-knoten-01 | Replica | running | | | + | | pg-knoten-01 | pg-knoten-03 | Replica | running | | |
| +--------------+--------------+---------+---------+----+-----------+ | +--------------+--------------+---------+---------+----+-----------+ | ||
| </ | </ | ||
| Zeile 1166: | Zeile 1026: | ||
| > patronictl -c / | > patronictl -c / | ||
| Current cluster topology | Current cluster topology | ||
| - | + Cluster: pgcluster (7637152973093863500) | + | + Cluster: pgcluster (7637152973093863500) -------+----+-----------+ |
| | Member | | Member | ||
| +--------------+--------------+---------+---------+----+-----------+ | +--------------+--------------+---------+---------+----+-----------+ | ||
| - | | pg-knoten-01 | pg-knoten-01 | Replica | running | | | + | | pg-knoten-01 | pg-knoten-03 | Replica | running | | |
| +--------------+--------------+---------+---------+----+-----------+ | +--------------+--------------+---------+---------+----+-----------+ | ||
| Candidate [' | Candidate [' | ||
| Are you sure you want to failover cluster pgcluster? [y/N]: y | Are you sure you want to failover cluster pgcluster? [y/N]: y | ||
| + | </ | ||
| + | |||
| + | <code bash > | ||
| + | > curl -s " | ||
| + | pg1 UP 1752 | ||
| + | pg2 DOWN -1 | ||
| + | pg3 DOWN -1 | ||
| + | BACKEND UP 1752 | ||
| + | pg1 DOWN -1 | ||
| + | pg2 DOWN -1 | ||
| + | pg3 DOWN -1 | ||
| + | BACKEND DOWN -1 | ||
| + | |||
| + | > patronictl -c / | ||
| + | + Cluster: pgcluster (7637598528541987072) -------+----+-----------+ | ||
| + | | Member | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | | pg-knoten-01 | pg-knoten-01 | Leader | ||
| + | | pg-knoten-02 | pg-knoten-02 | Replica | stopped | | | ||
| + | | pg-knoten-03 | pg-knoten-03 | Replica | stopped | | | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | |||
| + | |||
| + | Wenn das so aussieht, dann kann von den Replicas nicht gelesen werden. | ||
| + | Um das Problem zu beheben, müssen die Replicas (beide) reinitialisiert werden. | ||
| + | |||
| + | |||
| + | > patronictl -c / | ||
| + | + Cluster: pgcluster (7637598528541987072) -------+----+-----------+ | ||
| + | | Member | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | | pg-knoten-01 | pg-knoten-01 | Leader | ||
| + | | pg-knoten-02 | pg-knoten-02 | Replica | stopped | | | ||
| + | | pg-knoten-03 | pg-knoten-03 | Replica | stopped | | | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | Are you sure you want to reinitialize members pg-knoten-02? | ||
| + | Failed: reinitialize for member pg-knoten-02, | ||
| + | Do you want to cancel it and reinitialize anyway? [y/N]: y | ||
| + | Success: reinitialize for member pg-knoten-02 | ||
| + | |||
| + | > patronictl -c / | ||
| + | + Cluster: pgcluster (7637598528541987072) -------+----+-----------+ | ||
| + | | Member | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | | pg-knoten-01 | pg-knoten-01 | Leader | ||
| + | | pg-knoten-02 | pg-knoten-02 | Replica | stopped | | | ||
| + | | pg-knoten-03 | pg-knoten-03 | Replica | stopped | | | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | Are you sure you want to reinitialize members pg-knoten-03? | ||
| + | Failed: reinitialize for member pg-knoten-03, | ||
| + | Do you want to cancel it and reinitialize anyway? [y/ | ||
| + | |||
| + | |||
| + | Jetzt arbeiten die Replicas ordentliche und man kann von ihnen auch ordentlich lesen: | ||
| + | |||
| + | |||
| + | > patronictl -c / | ||
| + | + Cluster: pgcluster (7637598528541987072) ---------+----+-----------+ | ||
| + | | Member | ||
| + | +--------------+--------------+---------+-----------+----+-----------+ | ||
| + | | pg-knoten-01 | pg-knoten-01 | Leader | ||
| + | | pg-knoten-02 | pg-knoten-02 | Replica | streaming | 6 | 0 | | ||
| + | | pg-knoten-03 | pg-knoten-03 | Replica | streaming | 6 | 0 | | ||
| + | +--------------+--------------+---------+-----------+----+-----------+ | ||
| + | |||
| + | > curl -s " | ||
| + | pg1 UP 6000 | ||
| + | pg2 DOWN -1 | ||
| + | pg3 DOWN -1 | ||
| + | BACKEND UP 6000 | ||
| + | pg1 DOWN -1 | ||
| + | pg2 UP -1 | ||
| + | pg3 UP -1 | ||
| + | BACKEND UP -1 | ||
| + | </ | ||
| + | |||
| + | |||
| + | === Probleme nach kompletten Cluster-Neustart === | ||
| + | |||
| + | <code bash IST-Zustand> | ||
| + | > patronictl -c / | ||
| + | + Cluster: pgcluster (7637598528541987072) -------+----+-----------+ | ||
| + | | Member | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | | pg-knoten-01 | pg-knoten-01 | Replica | running | 13 | 217 | | ||
| + | | pg-knoten-02 | pg-knoten-02 | Replica | running | 13 | 217 | | ||
| + | | pg-knoten-03 | pg-knoten-03 | Replica | running | 13 | 217 | | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | </ | ||
| + | |||
| + | <code bash einen zum Leader bestimmen> | ||
| + | > patronictl -c / | ||
| + | + Cluster: pgcluster (7637598528541987072) -------+----+-----------+ | ||
| + | | Member | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | | pg-knoten-01 | pg-knoten-01 | Replica | running | 13 | 217 | | ||
| + | | pg-knoten-02 | pg-knoten-02 | Replica | running | 13 | 217 | | ||
| + | | pg-knoten-03 | pg-knoten-03 | Replica | running | 13 | 217 | | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | Candidate [' | ||
| + | Are you sure you want to failover cluster pgcluster? [y/N]: y | ||
| + | 2026-05-13 13: | ||
| + | + Cluster: pgcluster (7637598528541987072) -------+----+-----------+ | ||
| + | | Member | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | | pg-knoten-01 | pg-knoten-01 | Leader | ||
| + | | pg-knoten-02 | pg-knoten-02 | Replica | running | 13 | 217 | | ||
| + | | pg-knoten-03 | pg-knoten-03 | Replica | running | 13 | 217 | | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | |||
| + | > patronictl -c / | ||
| + | + Cluster: pgcluster (7637598528541987072) ---------+----+-----------+ | ||
| + | | Member | ||
| + | +--------------+--------------+---------+-----------+----+-----------+ | ||
| + | | pg-knoten-01 | pg-knoten-01 | Leader | ||
| + | | pg-knoten-02 | pg-knoten-02 | Replica | streaming | 14 | 0 | | ||
| + | | pg-knoten-03 | pg-knoten-03 | Replica | streaming | 14 | 0 | | ||
| + | +--------------+--------------+---------+-----------+----+-----------+ | ||
| </ | </ | ||
| Zeile 1340: | Zeile 1318: | ||
| //Immer erst mit Dirk Hartmann absprechen!// | //Immer erst mit Dirk Hartmann absprechen!// | ||
| + | |||
| + | <code bash Datenbanken und User zeigen> | ||
| + | > echo " | ||
| + | Password for user postgres: | ||
| + | List of databases | ||
| + | | ||
| + | -----------+----------+----------+-----------------+-------------+-------------+------------+-----------+----------------------- | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | (3 rows) | ||
| + | |||
| + | |||
| + | > echo " | ||
| + | Password for user postgres: | ||
| + | List of roles | ||
| + | Role name | | ||
| + | -----------+------------------------------------------------------------ | ||
| + | | ||
| + | | ||
| + | </ | ||
| + | |||
| + | <code bash> | ||
| + | > service keepalived stop | ||
| + | > service patroni stop | ||
| + | |||
| + | > / | ||
| + | > reboot && exit | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Status / Monitoring ==== | ||
| <file bash / | <file bash / | ||
| #!/bin/bash | #!/bin/bash | ||
| - | VERSION=" | + | #VERSION=" |
| + | VERSION=" | ||
| + | |||
| + | uptime | ||
| # KeepaliveD prüfen | # KeepaliveD prüfen | ||
| Zeile 1354: | Zeile 1369: | ||
| echo "# | echo "# | ||
| # PostgreSQL Commits | # PostgreSQL Commits | ||
| - | sudo -u postgres psql -t -c " | + | pg_isready -q && |
| # Active Connections | # Active Connections | ||
| - | sudo -u postgres psql -t -c " | + | pg_isready -q && |
| # HAProxy abfragen | # HAProxy abfragen | ||
| Zeile 1380: | Zeile 1395: | ||
| curl -s http:// | curl -s http:// | ||
| done | done | ||
| + | |||
| + | echo "# | ||
| + | pg_isready -q && echo " | ||
| + | FROM pg_settings | ||
| + | WHERE name IN ( | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | );" | sudo -u postgres psql | ||
| </ | </ | ||
| - | <code bash Netzwerkzugriff per HAProxy prüfen> | + | <file bash /root/bin/CPU-Nutzung.sh> |
| - | > echo " | + | #!/bin/bash |
| - | Password for user postgres: | + | |
| - | List of databases | + | |
| - | | + | |
| - | -----------+----------+----------+-----------------+-------------+-------------+------------+-----------+----------------------- | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | + | |
| - | | | | | + | |
| - | (3 rows) | + | |
| + | # Laufende Parallel‑Worker sehen | ||
| - | > echo "\du" | psql -h10.145.43.30 -p5433 -U postgres | + | echo " |
| - | Password for user postgres: | + | SELECT pid, backend_type, |
| - | List of roles | + | FROM pg_stat_activity |
| - | Role name | Attributes | + | WHERE backend_type LIKE ' |
| - | -----------+------------------------------------------------------------ | + | |
| - | postgres | + | SELECT backend_type, |
| - | repl | Replication | + | FROM pg_stat_activity |
| + | GROUP BY backend_type; | ||
| + | " | sudo -u postgres psql | ||
| + | </file> | ||
| + | |||
| + | <file bash / | ||
| + | # | ||
| + | |||
| + | echo "# Bonus: Alias wie SHOW PROCESSLIST" | ||
| + | echo " | ||
| + | CREATE VIEW show_processlist AS | ||
| + | SELECT | ||
| + | pid AS id, | ||
| + | usename AS " | ||
| + | client_addr AS host, | ||
| + | datname AS db, | ||
| + | state, | ||
| + | now() - query_start AS time, | ||
| + | query AS info | ||
| + | FROM pg_stat_activity; | ||
| + | " | sudo -u postgres | ||
| + | </ | ||
| + | |||
| + | <file bash / | ||
| + | # | ||
| + | |||
| + | |||
| + | echo "# Bonus: Alias wie SHOW PROCESSLIST" | ||
| + | echo " | ||
| + | SELECT * FROM show_processlist; | ||
| + | " | sudo -u postgres psql | ||
| + | </ | ||
| + | |||
| + | <file bash / | ||
| + | # | ||
| + | |||
| + | |||
| + | #echo "# pg_stat_activity" | ||
| + | #echo " | ||
| + | #SELECT * FROM pg_stat_activity; | ||
| + | #" | sudo -u postgres psql | ||
| + | |||
| + | #echo "### Praxisnahe Varianten (das, was man wirklich braucht)" | ||
| + | #echo "# Übersicht wie in MySQL" | ||
| + | #echo " | ||
| + | #SELECT | ||
| + | # pid, | ||
| + | # usename, | ||
| + | # datname, | ||
| + | # state, | ||
| + | # client_addr, | ||
| + | # application_name, | ||
| + | # backend_start, | ||
| + | # query_start, | ||
| + | # query | ||
| + | #FROM pg_stat_activity | ||
| + | #ORDER BY query_start DESC; | ||
| + | #" | sudo -u postgres psql | ||
| + | |||
| + | echo "# Nur aktive Queries (was läuft gerade)" | ||
| + | echo " | ||
| + | SELECT | ||
| + | pid, | ||
| + | usename, | ||
| + | now() - query_start AS runtime, | ||
| + | state, | ||
| + | query | ||
| + | FROM pg_stat_activity | ||
| + | WHERE state = ' | ||
| + | ORDER BY runtime DESC; | ||
| + | " | sudo -u postgres psql | ||
| + | |||
| + | echo "# Laufzeitkiller: | ||
| + | echo " | ||
| + | SELECT | ||
| + | pid, | ||
| + | usename, | ||
| + | now() - query_start AS runtime, | ||
| + | query | ||
| + | FROM pg_stat_activity | ||
| + | WHERE state = ' | ||
| + | AND now() - query_start > interval '5 minutes' | ||
| + | ORDER BY runtime DESC; | ||
| + | " | sudo -u postgres psql | ||
| + | |||
| + | echo "# Wer blockiert wen?" | ||
| + | echo " | ||
| + | SELECT | ||
| + | a.pid AS blocked_pid, | ||
| + | a.query AS blocked_query, | ||
| + | b.pid AS blocking_pid, | ||
| + | b.query AS blocking_query | ||
| + | FROM pg_locks bl | ||
| + | JOIN pg_stat_activity a ON a.pid = bl.pid | ||
| + | JOIN pg_locks kl | ||
| + | ON kl.locktype = bl.locktype | ||
| + | AND kl.database IS NOT DISTINCT FROM bl.database | ||
| + | AND kl.relation IS NOT DISTINCT FROM bl.relation | ||
| + | AND kl.page IS NOT DISTINCT FROM bl.page | ||
| + | AND kl.tuple IS NOT DISTINCT FROM bl.tuple | ||
| + | AND kl.transactionid IS NOT DISTINCT FROM bl.transactionid | ||
| + | AND kl.classid IS NOT DISTINCT FROM bl.classid | ||
| + | AND kl.objid IS NOT DISTINCT FROM bl.objid | ||
| + | AND kl.objsubid IS NOT DISTINCT FROM bl.objsubid | ||
| + | AND kl.pid != bl.pid | ||
| + | JOIN pg_stat_activity b ON b.pid = kl.pid | ||
| + | WHERE NOT bl.granted; | ||
| + | " | sudo -u postgres psql | ||
| + | |||
| + | #echo "### Sessions beenden (KILL QUERY / KILL CONNECTION)" | ||
| + | #echo "# Query abbrechen (sanft)" | ||
| + | #echo " | ||
| + | #SELECT pg_cancel_backend(pid) | ||
| + | #FROM pg_stat_activity | ||
| + | #WHERE pid = 12345; | ||
| + | #" | sudo -u postgres | ||
| + | |||
| + | #echo "# Session hart beenden" | ||
| + | #echo " | ||
| + | #SELECT pg_terminate_backend(pid) | ||
| + | #FROM pg_stat_activity | ||
| + | #WHERE pid = 12345; | ||
| + | #" | sudo -u postgres | ||
| + | |||
| + | echo "# Idle in transaction (sehr wichtig!)" | ||
| + | echo " | ||
| + | SELECT | ||
| + | pid, | ||
| + | usename, | ||
| + | now() - query_start AS idle_time, | ||
| + | query | ||
| + | FROM pg_stat_activity | ||
| + | WHERE state = 'idle in transaction' | ||
| + | ORDER BY idle_time DESC; | ||
| + | " | ||
| + | </ | ||
| + | |||
| + | <file bash / | ||
| + | # | ||
| + | |||
| + | |||
| + | if [ x = " | ||
| + | DBUSER=" | ||
| + | else | ||
| + | DBUSER=" | ||
| + | fi | ||
| + | |||
| + | echo "# Nur eigene DB / eigener User" | ||
| + | #echo " | ||
| + | #SELECT * | ||
| + | #FROM pg_stat_activity | ||
| + | #WHERE datname = current_database(); | ||
| + | #" | sudo -u postgres psql | ||
| + | |||
| + | #echo "# Oder" | ||
| + | echo " | ||
| + | SELECT * | ||
| + | FROM pg_stat_activity | ||
| + | WHERE usename = ' | ||
| + | " | sudo -u postgres psql | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Replica reinitialisieren ==== | ||
| + | |||
| + | <code bash pg-knoten-01 reparieren - neu syncen> | ||
| + | > patronictl -c / | ||
| + | + Cluster: pgcluster (7637598528541987072) | ||
| + | | Member | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | | pg-knoten-01 | pg-knoten-01 | Leader | ||
| + | | pg-knoten-02 | pg-knoten-02 | Replica | stopped | | | ||
| + | | pg-knoten-03 | pg-knoten-03 | Replica | stopped | | | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | Are you sure you want to reinitialize members pg-knoten-02? | ||
| + | Failed: reinitialize for member pg-knoten-02, status code=503, (bootstrap from leader ' | ||
| + | Do you want to cancel it and reinitialize anyway? [y/N]: y | ||
| + | Success: reinitialize for member pg-knoten-02 | ||
| </ | </ | ||
| - | //Wie das beste Vorgehen bei Wartungsarbeiten ist, muß erst noch ermittelt ausgelotet werden.// | + | |
| + | ==== failover ==== | ||
| <code bash> | <code bash> | ||
| - | > service keepalived stop | + | [root@FRA2C-MEDOS04]---------------------------------------------------------------------[0]-[0]-[2026-05-12 14:26:12] |
| - | > service | + | [~]# patronictl -c /etc/patroni/config.yml failover |
| + | Current cluster topology | ||
| + | + Cluster: pgcluster (7637598528541987072) ---------+----+-----------+ | ||
| + | | Member | ||
| + | +--------------+--------------+---------+-----------+----+-----------+ | ||
| + | | pg-knoten-01 | pg-knoten-01 | Replica | streaming | 8 | 0 | | ||
| + | | pg-knoten-02 | pg-knoten-02 | Leader | ||
| + | | pg-knoten-03 | pg-knoten-03 | Replica | streaming | 8 | 0 | | ||
| + | +--------------+--------------+---------+-----------+----+-----------+ | ||
| + | Candidate [' | ||
| + | Are you sure you want to failover cluster pgcluster, demoting current leader pg-knoten-02? | ||
| + | 2026-05-12 14: | ||
| + | + Cluster: pgcluster (7637598528541987072) -------+----+-----------+ | ||
| + | | Member | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| + | | pg-knoten-01 | pg-knoten-01 | Leader | ||
| + | | pg-knoten-02 | pg-knoten-02 | Replica | stopped | | | ||
| + | | pg-knoten-03 | pg-knoten-03 | Replica | running | 8 | 0 | | ||
| + | +--------------+--------------+---------+---------+----+-----------+ | ||
| - | > /root/bin/upgrade.sh ; sync ; /root/ | + | [root@FRA2C-MEDOS04]---------------------------------------------------------------------[0]-[0]-[2026-05-12 14:26:55] |
| - | > reboot && exit | + | [~]# patronictl -c /etc/patroni/config.yml list |
| + | + Cluster: pgcluster (7637598528541987072) ---------+----+-----------+ | ||
| + | | Member | ||
| + | +--------------+--------------+---------+-----------+----+-----------+ | ||
| + | | pg-knoten-01 | pg-knoten-01 | Leader | ||
| + | | pg-knoten-02 | pg-knoten-02 | Replica | streaming | 9 | 0 | | ||
| + | | pg-knoten-03 | pg-knoten-03 | Replica | streaming | 9 | 0 | | ||
| + | +--------------+--------------+---------+-----------+----+-----------+ | ||
| </ | </ | ||
| Zeile 1447: | Zeile 1668: | ||
| Write‑Traffic NUR zum Leader schicken | Write‑Traffic NUR zum Leader schicken | ||
| Read‑Traffic auf Replicas verteilen | Read‑Traffic auf Replicas verteilen | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== PostgreSQL-Tuning ===== | ||
| + | |||
| + | <code bash Daten asynchron einspielen, das geht etwas schneller> | ||
| + | > psql -c "SET synchronous_commit=off;" | ||
| + | </ | ||
| + | |||
| + | <code text> | ||
| + | Kurzfassung: | ||
| + | |||
| + | autovacuum_work_mem | ||
| + | effective_cache_size => 50% bis 75% der RAM-Größe | ||
| + | maintenance_work_mem => 3% bis 10% des RAM | ||
| + | max_connections | ||
| + | shared_buffers | ||
| + | |||
| + | frei verfügbarer RAM | ||
| + | work_mem ~ -------------------------------------------- | ||
| + | | ||
| + | |||
| + | work_mem ~ => ca. 1% der RAM-Größe; | ||
| + | </ | ||
| + | |||
| + | <file bash / | ||
| + | #!/bin/bash | ||
| + | |||
| + | # | ||
| + | VERSION=" | ||
| + | |||
| + | # | ||
| + | CLUSTER_NAME=" | ||
| + | |||
| + | ### RAM: 1547643 MB | ||
| + | # > echo " | ||
| + | # name | ||
| + | # ----------------------+-----------+------+--------------------+---------------------------------------------+------------ | ||
| + | # autovacuum_work_mem | ||
| + | # effective_cache_size | 148635648 | 8kB | configuration file | / | ||
| + | # maintenance_work_mem | 78643200 | ||
| + | # max_connections | ||
| + | # shared_buffers | ||
| + | # shared_memory_size | ||
| + | # work_mem | ||
| + | # (7 rows) | ||
| + | |||
| + | RAM_IN_MB=" | ||
| + | echo "RAM: ${RAM_IN_MB} MB" | ||
| + | |||
| + | S_PG=" | ||
| + | FROM pg_settings | ||
| + | WHERE name IN ( | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | );" | sudo -u postgres psql -t | head -n-1 | awk ' | ||
| + | echo " | ||
| + | # IST-Werte (ggf. autovacuum_work_mem = maintenance_work_mem): | ||
| + | ${S_PG} | ||
| + | " | ||
| + | |||
| + | AUTOVACUUM_WORK_MEM=" | ||
| + | EFFECTIVE_CACHE_SIZE=" | ||
| + | MAINTENANCE_WORK_MEM=" | ||
| + | MAX_CONNECTIONS=" | ||
| + | SHARED_BUFFERS=" | ||
| + | WORK_MEM=" | ||
| + | MAX_WAL_SIZE=" | ||
| + | |||
| + | echo "# empfohlene Werte, die meistens passen: | ||
| + | autovacuum_work_mem: | ||
| + | effective_cache_size: | ||
| + | maintenance_work_mem: | ||
| + | max_connections: | ||
| + | shared_buffers: | ||
| + | max_wal_size: | ||
| + | work_mem: | ||
| + | " | ||
| + | |||
| + | ### neu berechnete Werte, direkt setzen | ||
| + | ### patronictl -c / | ||
| + | echo "# | ||
| + | echo | ||
| + | jq -n \ | ||
| + | --arg ecs " | ||
| + | --arg mwm " | ||
| + | --arg mc " | ||
| + | --arg sb " | ||
| + | --arg mw " | ||
| + | --arg wm " | ||
| + | '{ | ||
| + | postgresql: { | ||
| + | parameters: { | ||
| + | effective_cache_size: | ||
| + | maintenance_work_mem: | ||
| + | max_connections: | ||
| + | shared_buffers: | ||
| + | max_wal_size: | ||
| + | wal_buffers: | ||
| + | checkpoint_timeout: | ||
| + | work_mem: $wm | ||
| + | } | ||
| + | } | ||
| + | }' | curl -s -X PATCH http:// | ||
| + | -H " | ||
| + | --data-binary @- | ||
| + | echo | ||
| + | echo "# | ||
| + | |||
| + | ### aktuelle Einstellungen anzeigen | ||
| + | patronictl -c / | ||
| + | |||
| + | ### neue Einstellungen aktivieren | ||
| + | ### shared_buffers benötigt leider einen Restart | ||
| + | service patroni restart | ||
| + | </ | ||
| + | |||
| + | <code bash RAM: 1547643 MB> | ||
| + | | ||
| + | ----------------------+-----------+------+--------------------+---------------------------------------------+------------ | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | (7 rows) | ||
| + | </ | ||
| + | |||
| + | <code bash Konfigurationsvorschlag nachher ansehen> | ||
| + | > / | ||
| + | RAM: 1547643 MB | ||
| + | |||
| + | # IST-Werte (ggf. autovacuum_work_mem = maintenance_work_mem): | ||
| + | effective_cache_size 1134 GB | ||
| + | maintenance_work_mem 151 GB | ||
| + | max_connections 150 | ||
| + | shared_buffers 378 GB | ||
| + | work_mem 15 GB | ||
| + | |||
| + | # empfohlene Werte, die meistens passen: | ||
| + | autovacuum_work_mem: | ||
| + | effective_cache_size: | ||
| + | maintenance_work_mem: | ||
| + | max_connections: | ||
| + | shared_buffers: | ||
| + | work_mem: | ||
| + | |||
| + | # | ||
| + | |||
| + | {" | ||
| + | # | ||
| + | loop_wait: 10 | ||
| + | maximum_lag_on_failover: | ||
| + | postgresql: | ||
| + | parameters: | ||
| + | effective_cache_size: | ||
| + | hot_standby: | ||
| + | maintenance_work_mem: | ||
| + | max_connections: | ||
| + | max_replication_slots: | ||
| + | max_wal_senders: | ||
| + | shared_buffers: | ||
| + | wal_level: replica | ||
| + | work_mem: 15GB | ||
| + | use_pg_rewind: | ||
| + | retry_timeout: | ||
| + | ttl: 30 | ||
| + | </ | ||
| + | |||
| + | <file bash / | ||
| + | #!/bin/bash | ||
| + | |||
| + | |||
| + | # Laufende Parallel‑Worker sehen | ||
| + | |||
| + | echo " | ||
| + | SELECT pid, backend_type, | ||
| + | FROM pg_stat_activity | ||
| + | WHERE backend_type LIKE ' | ||
| + | |||
| + | SELECT backend_type, | ||
| + | FROM pg_stat_activity | ||
| + | GROUP BY backend_type; | ||
| + | " | sudo -u postgres psql | ||
| + | </ | ||
| + | |||
| + | <code bash> | ||
| + | > / | ||
| + | pid | backend_type | state | ||
| + | -----+--------------+------- | ||
| + | (0 rows) | ||
| + | |||
| + | | ||
| + | -------------------+------- | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | (5 rows) | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Tests ===== | ||
| + | |||
| + | <code bash> | ||
| + | > time sudo -u postgres pgbench -i -s 1000 testdb | ||
| + | dropping old tables... | ||
| + | creating tables... | ||
| + | generating data (client-side)... | ||
| + | 100000000 of 100000000 tuples (100%) done (elapsed 85.93 s, remaining 0.00 s) | ||
| + | vacuuming... | ||
| + | creating primary keys... | ||
| + | done in 125.30 s (drop tables 4.04 s, create tables 0.01 s, client-side generate 86.85 s, vacuum 0.84 s, primary keys 33.56 s). | ||
| + | |||
| + | real 2m5.365s | ||
| + | user 0m0.038s | ||
| + | sys 0m0.077s | ||
| + | |||
| + | > sudo -u postgres pgbench -c 128 -j 128 -T 120 -N testdb | ||
| + | pgbench (16.13 (Ubuntu 16.13-0ubuntu0.24.04.1)) | ||
| + | starting vacuum...end. | ||
| + | transaction type: < | ||
| + | scaling factor: 1000 | ||
| + | query mode: simple | ||
| + | number of clients: 128 | ||
| + | number of threads: 128 | ||
| + | maximum number of tries: 1 | ||
| + | duration: 120 s | ||
| + | number of transactions actually processed: 5956017 | ||
| + | number of failed transactions: | ||
| + | latency average = 2.578 ms | ||
| + | initial connection time = 66.949 ms | ||
| + | tps = 49656.884083 (without initial connection time) | ||
| + | |||
| + | > sudo -u postgres pgbench -c 250 -j 250 -T 120 -N testdb | ||
| + | pgbench (16.13 (Ubuntu 16.13-0ubuntu0.24.04.1)) | ||
| + | starting vacuum...end. | ||
| + | transaction type: < | ||
| + | scaling factor: 1000 | ||
| + | query mode: simple | ||
| + | number of clients: 250 | ||
| + | number of threads: 250 | ||
| + | maximum number of tries: 1 | ||
| + | duration: 120 s | ||
| + | number of transactions actually processed: 6463558 | ||
| + | number of failed transactions: | ||
| + | latency average = 4.637 ms | ||
| + | initial connection time = 154.766 ms | ||
| + | tps = 53915.406631 (without initial connection time) | ||
| + | </ | ||
| + | |||
| + | <code bash WAL> | ||
| + | > echo " | ||
| + | | ||
| + | ----------------+--------------- | ||
| + | 0 | 0 | ||
| + | (1 row) | ||
| + | </ | ||
| + | |||
| + | <code bash ZFS I/O> | ||
| + | > zpool iostat -v | ||
| + | | ||
| + | pool | ||
| + | ----------- | ||
| + | pg_datadir | ||
| + | mirror-0 | ||
| + | nvme2n1 | ||
| + | nvme3n1 | ||
| + | ----------- | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Testdaten einspielen ==== | ||
| + | |||
| + | <code bash> | ||
| + | > echo "COPY tabelle FROM '/ | ||
| + | |||
| + | oder | ||
| + | |||
| + | > cat / | ||
| + | </ | ||
| + | |||
| + | <code bash Datensätze zählen> | ||
| + | > echo " | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Verbindungen SSL/ | ||
| + | |||
| + | |||
| + | ==== Verschlüsselung konfigurieren ==== | ||
| + | |||
| + | <code bash postgresql.conf> | ||
| + | > patronictl -c / | ||
| + | loop_wait: 10 | ||
| + | maximum_lag_on_failover: | ||
| + | postgresql: | ||
| + | parameters: | ||
| + | hot_standby: | ||
| + | max_replication_slots: | ||
| + | max_wal_senders: | ||
| + | wal_level: replica | ||
| + | ssl: on | ||
| + | ssl_ca_file: | ||
| + | ssl_cert_file: | ||
| + | ssl_key_file: | ||
| + | ssl_min_protocol_version: | ||
| + | ssl_ciphers: | ||
| + | ssl_prefer_server_ciphers: | ||
| + | use_pg_rewind: | ||
| + | retry_timeout: | ||
| + | ttl: 30 | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Verschlüsselung erzwingen ==== | ||
| + | |||
| + | <code bash pg_hba.conf> | ||
| + | > vim / | ||
| + | ... | ||
| + | pg_hba: | ||
| + | - hostnossl all all 0.0.0.0/0 reject | ||
| + | - hostnossl all all ::/0 reject | ||
| + | - hostssl replication all 0.0.0.0/0 scram-sha-256 | ||
| + | - hostssl replication all ::/0 scram-sha-256 | ||
| + | - hostssl all all 0.0.0.0/0 scram-sha-256 | ||
| + | - hostssl all all ::/0 scram-sha-256 | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== Verschlüsselung aktivieren ==== | ||
| + | |||
| + | <code bash kompletten Cluster restarten> | ||
| + | > patronictl -c / | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== temp_tablespaces ===== | ||
| + | |||
| + | <code bash temp_tablespaces-Verzeichnis anlegen> | ||
| + | > mkdir -p / | ||
| + | > chown postgres: | ||
| + | > chmod 0700 / | ||
| + | </ | ||
| + | |||
| + | <code bash temp_tablespaces konfigurieren> | ||
| + | > echo " | ||
| + | > echo " | ||
| + | > echo " | ||
| + | |||
| + | > patronictl -c / | ||
| + | ... | ||
| + | postgresql: | ||
| + | parameters: | ||
| + | temp_file_limit: | ||
| + | temp_tablespaces: | ||
| + | ... | ||
| </ | </ | ||
/home/http/wiki/data/attic/datenbank/ha-postgresql-cluster.1778608518.txt · Zuletzt geändert: von manfred
