Artiklis räägin, kuidas me lähenesime PostgreSQL tõrketaluvuse küsimusele, miks see meie jaoks tähtis on ja mida lõpuks saavutasime.
Meil on kõrge koormusega teenus: 2,5 miljonit kasutajat üle kogu maailma, 50K+ aktiivset kasutajat iga päev. Serverid asuvad Amazone'is ühes Iirimaa regioonis: töötab pidevalt üle 100 erineva serveri, sealhulgas peaaegu 50 andmebaasiga.
Kogu backend on suur monoliitne stateful-rakendus Java-s, mis hoiab pidevat websocket-ühendust kliendiga. Kui mitu kasutajat töötavad ühel tahvelarvutil, näevad nad kõik muudatusi reaalajas, kuna iga muudatus salvestatakse andmebaasi. Meil on ligikaudu 10K päringut sekundis meie andmebaasidele. Tipukoormuse ajal kirjutame Redis'sse 80-100K päringut sekundis.

Miks me läksime Rediselt PostgreSQL-ile üle
Alguses töötas meie teenus Redis'ega, võtme-väärtuse salvestusmoodul, mis salvestab kõik andmed mällu. serverile.
Redis'e plussid:
- Kõrge vastuse kiirus, kuna kõik on salvestatud mällu;
- Mugav varundamine ja replitseerimine.
Redis'e miinused meie jaoks:
- Reaalsete tehingute puudumine. Proovisime neid simuleerida meie rakenduse tasemel. Kahjuks ei toiminud see alati hästi ja nõudis väga keerulise koodi kirjutamist.
- Andmete maht on piiratud mälu hulgaga. Andmete suurenedes kasvab mälu ja lõpuks jõuame valitud instantsi omadustesse, mis AWS-is nõuab meie teenuse peatamist instantsitüübi muutmiseks.
- Madala latentsuse taseme pidev säilitamine on vajalik, kuna meil on väga palju päringuid. Meie jaoks on optimaalne latentsuse tase 17-20 ms. 30-40 ms taseme puhul saame meie rakenduse päringutele aeglaseid vastuseid ja teenuse halvenemist. Kahjuks juhtus see meil septembris 2018, kui üks Redis instants sai mingil põhjusel kaks korda suurema latentsuse. Probleemi lahendamiseks peatamine teenus keset tööpäeva ettenägematu hoolduse jaoks ja probleemne Redis instants asendati.
- Andmete konsistentsi kergesti saavutamine isegi kergemate koodivigade korral ja seejärel kulutada palju aega nende andmete parandamiseks koodi kirjutamisele.
Oleme arvesse võtnud puudused ja mõistnud, et peame liikuma millegi mugavama suunas, et teha normaalseid tehinguid ja vähendada latentsuse sõltuvust. Tegime uuringu, analüüsisime hulgaliselt varianta ja valisime PostgreSQL-i.
Oleme uut andmebaasi kasutusele võtnud juba 1,5 aastat ja kolinud ainult väikese osa andmetest, seega töötame praegu samaaegselt Redis'i ja PostgreSQL-i peal. Üksikasjalikumalt ülemineku etappidest ja andmete vahetamisest andmebaaside vahel on kirjutatud minu kolleegi artiklis.
Kui me alles alustasime üleminekut, töötas meie rakendus otse andmebaasiga ja side toimus Redis'i ja PostgreSQL'i emaga. PostgreSQL klasster koosnes emast ja replikast, kasutades asünkroonset replikatsiooni. Nii nägi välja andmebaasidega töötamise skeem:

PgBouncer'i juurutamine
Selle ülemineku ajal arenes toode samuti: kasutajate arv ja PostgreSQL-i teenindavate serverite arv suurenes ning meil jäi ühendustest puudu. PostgreSQL loob iga ühenduse jaoks eraldi protsessi, mis tarbib ressursse. Ühenduste arvu saab suurendada kuni teatud punktini, muidu on oht saada andmebaasi ebapiisav töö. Sellises olukorras on ideaalne lahendus ühenduste halduri valimine, mis paigaldatakse andmebaasi ette.
Meil oli kaks valikut ühenduste haldurile: Pgpool ja PgBouncer. Kuid esimene ei toeta andmebaasiga töötamise tehingurežiimi, seetõttu valisime PgBounceri.
Me seadistasime järgmise töö skeemi: meie rakendus pöördub ühe PgBounceri poole, mille taga on PostgreSQL-i peamised serverid ning iga peaserveri taga on üks replikatsioon asünkroonse replikatsiooniga.

Kuna me ei saanud salvestada kogu andmemahtu PostgreSQL-i ning kiirus andmebaasiga töötamisel oli meile oluline, alustasime PostgreSQL-i shardimist rakendustasandil. Ülaltoodud skeem on selleks suhteliselt mugav: uue shardi lisamisel on piisav lihtsalt PgBounceri konfiguratsiooni uuendamine ja rakendus saab kohe uue shardiga töötada.
PgBounceri talitlushäired
See skeem töötas, kuni ainus PgBounceri instants kukkus ära. Oleme AWS-is, kus kõik instantsid töötavad riistvaral, mis perioodiliselt loobub elust. Sellistel juhtudel lihtsalt migreeritakse instants uutesse seadmetesse ja see töötab jälle. Nii juhtus ka PgBounceriga, kuid see muutus kättesaamatuks. Selle languse tulemuseks oli meie teenuse kättesaamatuse kestus 25 minutit. AWS soovitab selliste olukordade puhul kliendipoolset üleliigset lahendust, mida meil tol ajal ei olnud.
Pärast seda hakkasime tõsiselt mõtlema PgBounceri ja PostgreSQL klastrite talitlushäirele, sest sarnane situatsioon võiks korduda iga instantsiga meie AWS kontol.
Meie PgBounceri häirekavand on ehitatud järgmiselt: kõik rakenduste serverid suunavad liikluse Network Load Balancerile, mille taga on kaks PgBouncerit. Iga PgBouncer jälgib iga shard'i samu master PostgreSQL servereid. Kui AWS-i instantsi tõrge kordub, suunatakse kogu liiklus teise PgBounceri kaudu. Network Load Balancer tagab AWS-i kaudu kõrge kättesaadavuse.
Selline skeem võimaldab probleemideta lisada uusi PgBounceri servereid.

Häirekõrguseta PostgreSQL klastrite loomine
Selle ülesande lahendamisel vaatasime erinevaid võimalusi: käsitsi kirjutatud failover, repmgr, AWS RDS, Patroni.
Kohandatud skriptid
Need saavad monitoorda masteri toimimist ja, kui see ebaõnnestub, edendada koopiat masteriks ning uuendada PgBounceri konfiguratsiooni.
Selle lähenemise plussid seisnevad maksimaalses lihtsuses, kuna kirjutate skripte ise ja mõistate täpselt, kuidas need töötavad.
Miinused:
- Master ei pruugi olla surnud, võib-olla toimus võrgu tõrge. Kui failover ei tea sellest, edendab see koopiat masteriks ning vana master jääb töötama. Tulemuseks on kaks serverit masterina ja me ei tea, milles neist on viimased andmed. Sellist olukorda nimetatakse ka split-brain'iks.
- Meil on olnud mure replika puudumise osas. Meie konfiguratsioonis on master ja üks replikatsioon, pärast switch'i edeneb replika masteriks ja meil ei ole enam replikaid, seetõttu peame käsitsi lisama uue replika.
- Failoveri täiendav jälgimine on vajalik, meil on 12 PostgreSQL shard'i, seega peame jälgima 12 klastrit. Shardide arvu suurenedes tuleb failover'i samuti värskendada.
Kohandatud failover näib väga keeruline ja vajab mittetavalist tuge. Ühe PostgreSQL klastri puhul oleks see lihtsaim lahendus, kuid see ei ole skaleeritav, seega ei sobi see meile.
Repmgr
PostgreSQL klastrite replikatsiooni haldur, mis suudab hallata PostgreSQL klastrite tööd. Samas ei ole seal automaatset failover'i 'karbist', seega on vajalik kirjutada oma 'ümbrik' valmis lahenduse peale. Seetõttu võib kõik osutuda isegi keerulisemaks kui kohandatud skriptidega, mistõttu me ei proovinudki Repmgr'i.
AWS RDS
Toetab kõike vajalikku, suudab teha varukoopiaid ja toetab ühenduste kogumit. Omab automaatselt üleminekut: kui põhiserver sureb, muutub replikatsioon uuesti peamiseks serveriks ja AWS muudab DNS-kirje uut põhiserverit, samas kui replikatsioonid võivad asuda erinevates AZ-des.
Miinusteks on võimalikud peened seadistused. Näiteks peente seadistuste osas: meie instantsidel on piirangud TCP ühenduste jaoks, mida kahjuks RDS-is teha ei saa:
net.ipv4.tcp_keepalive_time=10
net.ipv4.tcp_keepalive_intvl=1
net.ipv4.tcp_keepalive_probes=5
net.ipv4.tcp_retries2=3
Lisaks on AWS RDS hind peaaegu kaks korda kallim kui tavalise instantsi hind, mis oli peamine põhjus selle lahenduse tagasi lükkamiseks.
Patroni
See on Python'i mall PostgreSQL-i haldamiseks, millel on hea dokumentatsioon, automaatne rike ja lähtekood GitHubis.
Patroni plusse:
- Iga konfiguratsiooniparameeter on selgelt kirjas, kuidas miski töötab;
- Automaatne rikete üleminek töötab välja karbist;
- Kirjutatud Python'is, ja kuna me ise kirjutame palju Python'is, on meil lihtsam probleemidega tegeleda ja võib-olla isegi aidata projekti arengus;
- Haldab täielikult PostgreSQL-i, võimaldades konfigureerida kõiki klastrite sõlmi. Kui uue konfiguratsiooni rakendamiseks on vajalik klastrite taaskäivitamine, saab seda teha taas Patroni abil.
Miinused:
- Dokumendist ei ole selge, kuidas PgBounceriga õigesti töötada. Kuigi seda on keeruline nimetada miinuseks, kuna Patroni ülesanne on hallata PostgreSQL-i ja kuidas ühendused Patroniga toimuvad, on juba meie probleem.
- Patroni juurutamiseks suuremates mahus on vähe näiteid, samas on palju näiteid juurutamisest nullist.
Lõpuks valisime usaldusväärse klastrite loomise jaoks just Patroni.
Patroni juurutamisprotsess
Enne Patronit oli meil 12 PostgreSQL-i shard'i, mis olid konfigureeritud ühe meistri ja ühe replikaga, mille replikatsioon oli asünkroonset tüüpi. Rakenduste serverid pöördusid andmebaaside poole läbi Network Load Balanceri, mille taga olid kaks PgBounceri instantsi, ning nende taga kõik PostgreSQL serverid.

Patroni rakendamiseks pidime valima klastrite konfiguratsiooni jaotatud salvestusruumi. Patroni töötab koos jaotatud konfiguratsioonihaldussüsteemidega, nagu etcd, Zookeeper, Consul. Meil on tootmises täielik Consul klaster, mis töötab koos Vaultiga ja me ei kasuta seda muul viisil. Suurepärane võimalus hakata Consulit õigesti kasutama.
Kuidas Patroni töötab Consuliga
Meil on Consul klaster, mis koosneb kolmest node'ist, ja Patroni klaster, mis koosneb liidristruktuurist ja replikast (Patronis nimetatakse master'it klastriliidriks ja slavenid - replikateks). Iga Patroni klastrite instants saadab pidevalt Consulile teavet klastriseisundi kohta. Seetõttu saab Consulist alati teada Patroni klastrite praegust konfiguratsiooni ja kes on hetkel liider.

Patroni ühendamiseks Consuliga on piisav tutvuda ametliku dokumentatsiooniga, kus on kirjas, et tuleb näidata hosti formaadis http või https, sõltuvalt sellest, kuidas me Consuliga töötame, ning ühenduse skeem, mis on valikuline:
host: host:port Consul lõpp-punkti jaoks, vormingus: http(s)://host:port
scheme: (valikuline) http või https, vaikimisi httpTundub lihtne, kuid siin algavad komistuskivid. Konsuliga töötame me kaitstud ühenduse kaudu https ja meie ühenduse konfigureerimine näeb välja järgmine:
consul:
host: https://server.production.consul:8080
verify: true
cacert: {{ consul_cacert }}
cert: {{ consul_cert }}
key: {{ consul_key }}Aga see ei toimi. Patroni käivitamisel ei saa see Konsuliga ühendust luua, kuna see üritab ikkagi minna http kaudu.
Probleemi lahendamisel aitas Patrioni allikas. Hea, et see on kirjutatud pythonis. Selgub, et host-parameetrit ei analüüsita, vaid protokoll tuleb määrata skeemi all. Nii näeb välja töötav konfigureerimissegment Konsuliga töötamiseks meie jaoks:
consul:
host: server.production.consul:8080
scheme: https
verify: true
cacert: {{ consul_cacert }}
cert: {{ consul_cert }}
key: {{ consul_key }}Consul-template
Nii oleme valinud konfiguratsiooniks hoiuruumi. Nüüd peame aru saama, kuidas PgBouncer vahetab oma konfiguratsiooni, kui Patroni klastris liider vahetub. Sellele küsimusele ei leia dokumentatsioonist vastust, kuna seal ei ole põhimõtteliselt kirjeldatud koostööd PgBounceriga.
Lahenduse otsingutel leidsime artikli (pealkiri, kahjuks, ei meenu), kus oli kirjutatud, et Consul-template aitas väga hästi PgBounceri ja Patroni vahel. See suunas meid uurima Consul-template'i toimimist.
Selgus, et Сonsul-template jälgib pidevalt PostgreSQL klastri konfiguratsiooni Сonsuli kaudu. Juhtide vahetamisel uuendab ta PgBounceri konfiguratsiooni ja saadab käsu selle taaskäivitamiseks.

Suur pluss template'is on see, et see salvestatakse koodina, seega piisab uue shard'i lisamisest lihtsalt uue commit'i tegemisel ja template'i automaatsest uuendamisest, toetades Infrastructure as code põhimõtet.
Uus arhitektuur koos Patroniga
Tulemuseks saime sellise töö схем:

Kõik rakenduste serverid pöörduvad tasakaalustaja poole → selle taga on kaks PgBounceri instantsi → igal instantsil on käimas Сonsul-template, mis jälgib iga Patroni klastri olekut ja hoolitseb PgBounceri konfi ajakohasuse eest, mis suunab päringud iga klastri praegusele juhile.
Käsitsi testimine
Selle skeemi enne tootmisse viimist käivitasime väikese testkeskkonna ja kontrollisime automaatse ülemineku toimimist. Avatud tahvlil liikusime kleebist ja sel hetkel 'tapsime' klastri juhi. AWS-is piisab selleks instantsi konsoolist väljalülitamisest.

Siltik tuli tagasi 10-20 sekundi jooksul, seejärel hakkas jälle normaalselt liikuma. See tähendab, et Patroni klaster töötas õigesti: vahetas liidri, edastas teabe Consulile ja Consul-template haaras selle teabe kohe, asendas PgBounceri konfiguratsiooni ja edastas käsu reload.
Kuidas ellu jääda kõrge koormuse all ja säilitada minimaalne seisak?
Kõik töötab suurepäraselt! Kuid uusi küsimusi tekib: Kuidas see töötab kõrge koormuse all? Kuidas kiiresti ja ohutult kõike tootmisse rakendada?
Esimesele küsimusele aitab vastata testkeskkond, kus teeme koormustestimist. See on täielikult identne tootmisele arhitektuurilt ja sisaldab genereeritud testandmeid, mille maht on umbes sama suur nagu tootmises. Otsustame lihtsalt “tappa” ühe PostgreSQL peamise serveri testi ajal ja vaadata, mis juhtub. Kuid enne seda on oluline kontrollida automaatset rakendamist, sest sellel keskkonnas on meil mitu PostgreSQL shard'i, nii et saame suurepärase konfiguratsiooniskeemide testimise enne tootmist.
Mõlemad ülesanded tunduvad ambitsioonikad, kuid meil on PostgreSQL 9.6. Kas tõstame kohe versioonile 11.2?
Kavandame seda teha kahes etapis: esmalt uuendame versiooni 11.2-le ja seejärel käivitame Patroni.
PostgreSQL uuendamine
PostgreSQL versiooni kiireks uuendamiseks tuleb kasutada valikut -k, milles luuakse kõvakettale hard link ja teie andmete kopeerimist pole vaja. 300-400 GB suuruste andmebaaside puhul võtab uuendamine aega 1 sekund.
Meil on palju sharde, seega peab uuendamine toimuma automaatrežiimis. Selleks kirjutasime Ansible playbook'i, mis viib kogu uuendamisprotsessi läbi meie eest:
/usr/lib/postgresql/11/bin/pg_upgrade
<b>--link </b>
--old-datadir='' --new-datadir=''
--old-bindir='' --new-bindir=''
--old-options=' -c config_file='
--new-options=' -c config_file='Siinkohal on oluline märkida, et enne uuenduse käivitamist tuleb see teha parameetriga --check, et veenduda uuendamise võimalikkuses. Samuti teeb meie skript uuendamise ajaks konfiguratsioonifailide vahetuse. Meie skript käivitati 30 sekundi jooksul, see on suurepärane tulemus.
Patroni käivitamine
Teise probleemi lahendamiseks piisab, kui vaadata Patroni konfiguratsiooni. Ametlikus hoidlas on olemas initdb konfiguratsiooni näidis, mis vastutab uue andmebaasi initsialiseerimise eest Patroni esmakordsel käivitamisel. Kuna meil on juba valmis andmebaas, eemaldasime lihtsalt selle osa konfiguratsioonist.
Kui alustasime Patroni seadistamist juba valmis PostgreSQL klastrile ja selle käivitamist, siis kohtasime uut probleem: mõlemad serverid käivituvad kui liidrid. Patroni ei tea klastrite varasest seisundist ja üritab käivitada mõlemat serverit nagu kahte eraldi klastrit sama nimega. Selle probleemi lahendamiseks tuleb kustutada slaavi andmed direktori:
rm -rf /var/lib/postgresql/Seda tuleb teha ainult slaavil!
Puhas replikatsioon ühendamisel teeb Patroni liidri baasi varukoopia ja taastab selle replikatsioonile, seejärel jõuab aktuaalsesse seisundisse läbi wal-logide.
Veel üks keerukus, millega me kokku puutusime, on see, et kõik PostgreSQL klastrid kannavad vaikimisi nime main. Kui iga klaster ei tea teistest midagi, on see normaalne. Kuid kui soovite kasutada Patronit, peavad kõik klastrid omama unikaalset nime. Lahendus on muuta PostgreSQL konfiguratsioonis klastrinime.
Koormustest
Me käivitasime testi, mis jäljendab kasutajate tegevust tahvlitel. Kui koormus jõudis meie keskmisele päevatasemele, viisime läbi täpselt sama testi, lülitades välja ühe PostgreSQL juhi esinduse. Automatiseeritud failover toimis meie ootuste kohaselt: Patroni vahetas juhti, Consul-template uuendas PgBounceri konfiguratsiooni ja käskis ta uuesti laadida. Meie Grafanas nähtavatest graafikutest oli näha, et oli 20-30 sekundi pikkused viivitused ja väike hulk vigu serveritest, mis olid seotud andmebaasi ühendustega. See on normaalne olukord, sellised näitajad on meie failover'i jaoks vastuvõetavad ja kindlasti paremad kui teenuse seiskumine.
Patroni väljund tootmises
Kokkuvõttes saime järgmise plaani:
- Consul-template'i juurutamine PgBounceri serveritesse ja käivitamine;
- PostgreSQL versiooni 11.2 uuendamine;
- Klastri nime muutmine;
- Patroni klastri käivitamine.
Samal ajal võimaldab meie skeem esimese punkti teostada praktiliselt igal ajal, saame järk-järgult iga PgBounceri välja lülitada ning teostada sellele juurutamise ja Consul-template'i käivitamise. Just seda me tegime.
Kiirete juurutuste jaoks kasutasime Ansible'i, kuna kõik playbook'id olime juba testkeskkonnas üle kontrollinud ning täissaneerimise kestus iga shard’i kohta oli 1,5 kuni 2 minutit. Me oleksime saanud kõik järk-järgult iga shard'i peale käivitada ilma meie teenuse peatamiseta, kuid oleksime pidanud iga PostgreSQL mõneks minutiks välja lülitama. Sellisel juhul ei saaks need kasutajad, kelle andmed on sellel shard'il, sel ajal täielikult töötada, mis on meie jaoks vastuvõetamatu.
Selle olukorra lahenduseks sai planeeritud hooldus, mis toimub meil iga kolm kuu tagant. See on aken planeeritud töödeks, mille käigus lülitame meie teenuse täielikult välja ja uuendame andmebaasi instantsid. Järgmise aknani oli jäänud nädal ja otsustasime lihtsalt oodata ja täiendavalt valmistuda. Ootamise ajal kindlustasime end täiendavalt: iga shard'i jaoks tõstsime üles varureplika, et ära hoida ebaõnnestumist ja säilitada kõige värskemad andmed, ning lisasime iga shard'i jaoks uue instantsi, mis peab olema uus replikator Patroni klastris, et mitte käivitada andmete kustutamise käsku. Kõik see aitas maksimaalselt vähendada vea riski.

Oleme meie teenuse taaskäivitanud, kõik töötab nagu peab, kasutajad said jätkata tööd, kuid graafikud näitasid ebanormaalset kõrget koormust Consul-serveritele.

Miks me seda testkeskkonnas ei näinud? See probleem illustreerib väga selgelt, et on hädavajalik järgida printsiipi „Infrastruktuur kui kood” ja täiustada kogu infrastruktuuri alates testkeskkondadest kuni tootmiseni. Vastasel juhul on väga lihtne saada selline probleem, nagu meil oli. Mis juhtus? Consul ilmus esmalt tootmisse ja alles hiljem testkeskkondadesse, tulemuseks oli see, et testkeskkondades oli Consuli versioon kõrgem kui tootmises. Just ühes versiooniväljaandes lahendati CPU lekkimine consul-template'i kasutamisel. Seetõttu värskendasime lihtsalt Consuli, lahendades niiviisi probleemi.
Taaskäivita Patroni klaster
Kuid saime uue probleemi, millest isegi ei kahtlustanud. Consuli uuendamisel eemaldame lihtsalt Consuli sõlme klastrist käsuga consul leave → Patroni ühendub teise Consuli serveriga → kõik töötab. Kuid kui jõudsime klastris viimasele Consuli instantsile ja saatsime talle käsu consul leave, taaskäivitusid kõik Patroni klastrid, ja logides nägime järgmist viga:
VIGA: get_cluster
Viga jälgimine (viimase kõne sisu):
...
RetryFailedError: 'Ületatud uuesti proovimise tähtaeg'
VIGA: Viga suhtlemisel DCS-iga
<b>LOGI: andmebaasi süsteem on välja lülitatud</b>Patroni klaster ei saanud teavet oma klastrist ja taaskäivitati.
Otsides lahendust, pöördusime Patroni autorite poole GitHubi teema kaudu. Nad pakkusid meie konfiguratsioonifailide täiustusi:
consul:
consul.checks: []
bootstrap:
dcs:
retry_timeout: 8Me suutsime probleemi testkeskkonnas korrata ja testisime seal neid parameetreid, kuid kahjuks need ei töötanud.
Probleem on endiselt lahendamata. Plaanime proovida järgmisi lahendusi:
- Kasutada Consul-agent’i igas Patroni klastris asuvas instantsis;
- Parandada probleem koodis.
Meile on selge vea tekkimise koht: probleem on tõenäoliselt default timeout’i kasutamises, mida ei ümberdefineerita konfiguratsioonifaili kaudu. Kui viimane Consul server eemaldatakse klastrist, hangub kogu Consul klaster, mis kestab kauem kui sekund, mistõttu Patroni ei saa klastriseisundit ja taaskäivitab kogu klastrit.
Õnneks ei ole me kohanud mingeid muid vigu.
Patroni kasutamise tulemused
Pärast Patroni edukat käivitamist lisasime igasse klastrisse ühe täiendava repliigi. Nüüd on igas klastris mingi liik, kus on üks liider ja kaks repliiki — et kaitsta jagatud aju olukorra korral vahetamisel.

Patroni on tootmises olnud üle kolme kuu. Selle aja jooksul on see meid juba päästnud. Hiljuti suri AWS-is ühe klastri liider, automaatne failover töötas ja kasutajad said jätkata tööd. Patroni täitis oma peamise eesmärgi.
Patroni kasutamise väike kokkuvõte:
- Asetuste muutmise mugavus. Piisab muudatusest ühes instantsis ja see tõmmatakse kogu klastrisse. Kui uue seadistuse rakendamiseks on vajalik taaskäivitamine, siis Patroni teavitab sellest. Patroni saab kogu klastrit taaskäivitada ühe käsuga, mis on samuti väga mugav.
- Automaatne failover töötab ja on meid juba aidanud.
- PostgreSQL-i uuendamine ilma rakenduse seiskamiseta. Esiteks tuleb uuendada repliigid uuele versioonile, seejärel vahetada klastri Patroni liider ja uuendada vana liider. Sellega toimub vajalik automaatse failoveri testimine.
Allikas: habr.com
