PostgreSQL kan afzonderlijk werken op meerdere machines met dezelfde gegevensstructuur, waardoor de persistentielaag van de applicatie veerkrachtiger wordt en voorbereid is op een onverwachte gebeurtenis die de continuïteit van de service in gevaar kan brengen.
Het idee hierachter is om de reactietijd van het systeem te verbeteren door de verzoeken te distribueren in een "Round Robin"-netwerk waarbij elk aanwezig knooppunt een cluster is. In dit type configuratie is het niet belangrijk aan welke de verzoeken zullen worden geleverd om te worden verwerkt, omdat het antwoord altijd hetzelfde zou zijn.
In deze blog leggen we uit hoe je een PostgreSQL-cluster kunt repliceren met behulp van de tools die bij de programma-installatie zijn geleverd. De gebruikte versie is PostgreSQL 11.5, de huidige stabiele, algemeen beschikbare versie voor het besturingssysteem Debian Buster. Voor de voorbeelden in deze blog wordt er vanuit gegaan dat je al bekend bent met Linux.
PostgreSQL-programma's
In de directory /usr/bin/ bevindt zich het programma dat verantwoordelijk is voor het beheer van het cluster.
# 1. Lists the files contained in the directory
# 2. Filters the elements that contain 'pg_' in the name
ls /usr/bin/ | grep pg_
Activiteiten die via deze programma's worden uitgevoerd, kunnen opeenvolgend worden uitgevoerd, of zelfs in combinatie met andere programma's. Een blok van deze activiteiten uitvoeren via een enkele opdracht is mogelijk dankzij een Linux-programma dat in dezelfde map staat, genaamd make.
Gebruik het programma pg_lsclusters om de aanwezige clusters weer te geven. U kunt ook make gebruiken om het uit te voeren. Zijn werk hangt af van een bestand met de naam Makefile, dat zich in dezelfde map moet bevinden als waar de opdracht wordt uitgevoerd.
# 1. The current directory is checked
pwd
# 2. Creates a directory
mkdir ~/Documents/Severalnines/
# 3. Enroute to the chosen directory
cd ~/Documents/Severalnines/
# 4. Create the file Makefile
touch Makefile
# 5. Open the file for editing
De definitie van een blok wordt hieronder getoond, met als naam ls, en een enkel uit te voeren programma, pg_lsclusters.
# 1. Block name
ls:
# 2. Program to be executed
pg_lsclusters
Het bestand Makefile kan meerdere blokken bevatten, en elk kan zoveel programma's uitvoeren als je nodig hebt, en zelfs parameters ontvangen. Het is absoluut noodzakelijk dat de regels die bij een uitvoeringsblok horen correct zijn, waarbij tabellen worden gebruikt voor inspringen in plaats van spaties.
Het gebruik van make om het programma pg_lsclusters uit te voeren wordt bereikt door het commando make ls te gebruiken.
# 1. Executes pg_lsclusters
make ls
Het resultaat verkregen in een recente PostgreSQL-installatie brengt een enkel cluster genaamd main, toegewezen op poort 5432 van het besturingssysteem. Wanneer het programma pg_createcluster wordt gebruikt, wordt een nieuwe poort toegewezen aan het nieuwe cluster dat is gemaakt, met de waarde 5432 als startpunt, totdat een andere wordt gevonden in oplopende volgorde.
Write Ahead Logging (WAL)
Deze replicatieprocedure bestaat uit het maken van een back-up van een werkend cluster dat updates blijft ontvangen. Als dit echter op dezelfde machine wordt gedaan, gaan veel van de voordelen van deze techniek verloren.
Horizontaal schalen van een systeem zorgt voor een grotere beschikbaarheid van de service. Als er hardwareproblemen optreden, zou het niet veel uitmaken omdat er andere machines klaar staan om de werklast op zich te nemen.
WAL is de term die wordt gebruikt om een intern complex algoritme voor PostgreSQL te vertegenwoordigen dat de integriteit van de transacties die op het systeem worden gedaan, garandeert. Er hoeft echter maar één cluster de verantwoordelijkheid te hebben om er toegang toe te krijgen met schrijfrechten.
De architectuur heeft nu drie verschillende typen clusters:
- Een primaire verantwoordelijke voor het schrijven naar WAL;
- Een replica klaar om de primaire post over te nemen;
- Diverse andere replica's met WAL-leesplicht.
Schrijfbewerkingen zijn alle activiteiten die bedoeld zijn om de gegevensstructuur te wijzigen, hetzij door nieuwe elementen in te voeren, hetzij door bestaande records bij te werken en te verwijderen.
PostgreSQL-clusterconfiguratie
Elk cluster heeft twee mappen, een met de configuratiebestanden en een andere met de transactielogboeken. Deze bevinden zich respectievelijk in /etc/postgresql/11/$(cluster) en /var/lib/postgresql/11/$(cluster), (waarbij $(cluster) de naam van het cluster is).
Het bestand postgresql.conf wordt gemaakt onmiddellijk nadat het cluster is gemaakt door het programma pg_createcluster uit te voeren, en de eigenschappen kunnen worden gewijzigd om een cluster aan te passen.
Het wordt niet aanbevolen om dit bestand rechtstreeks te bewerken omdat het bijna alle eigenschappen bevat. Hun waarden zijn becommentarieerd, met het symbool # aan het begin van elke regel, en verschillende andere regels zijn becommentarieerd met instructies voor het wijzigen van de eigenschapswaarden.
Het is mogelijk om nog een bestand toe te voegen dat de gewenste wijzigingen bevat. Bewerk eenvoudig een enkele eigenschap met de naam include en vervang de standaardwaarde #include ='' door include ='postgresql.replication.conf'.
Voordat u het cluster start, moet het bestand postgresql.replication.conf aanwezig zijn in dezelfde map waar u het originele configuratiebestand vindt, genaamd postgresql.conf.
# 1. Block name
create:
# 2. Creates the cluster
pg_createcluster 11 $(cluster) -- --data-checksums
# 3. Copies the file to the directory
cp postgresql.replication.conf /etc/postgresql/11/$(cluster)/
# 4. A value is assigned to the property
sed -i "s|^#include = ''|include = 'postgresql.replication.conf'|g" /etc/postgresql/11/$(cluster)/postgresql.conf
Het gebruik van --data-checksums bij het maken van het cluster voegt een hoger niveau van integriteit toe aan de gegevens, wat wat prestatie kost, maar erg belangrijk is om corruptie van de bestanden te voorkomen wanneer overgedragen van het ene cluster naar het andere.
De hierboven beschreven procedures kunnen worden hergebruikt voor andere clusters, door simpelweg een waarde door te geven aan $(cluster) als parameter bij de uitvoering van het programma make.
# 1. Executes the block 'create' by passing a parameter
sudo make create cluster=primary
Nu een korte automatisering van de taken tot stand is gebracht, moet er nog worden gewerkt aan de definitie van het bestand postgresql.replication.conf volgens de behoefte voor elk cluster.
Replicatie op PostgreSQL
Er zijn twee manieren om een cluster te repliceren, de ene is compleet, de andere de hele cluster (genaamd Streaming Replication) en een andere kan gedeeltelijk of volledig (Logische Replicatie genoemd).
De instellingen die voor een cluster moeten worden opgegeven, vallen in vier hoofdcategorieën:
- Hoofdserver
- Stand-byservers
- Servers verzenden
- Abonnees
Zoals we eerder zagen, is WAL een bestand dat de transacties bevat die op het cluster zijn gedaan, en de replicatie is de overdracht van deze bestanden van het ene cluster naar het andere.
Binnen de instellingen die aanwezig zijn in het bestand postgresql.conf, kunnen we eigenschappen zien die het gedrag van het cluster in relatie tot de WAL-bestanden definiëren, zoals de grootte van die bestanden.
# default values
max_wal_size = 1GB
min_wal_size = 80MB
Een andere belangrijke eigenschap genaamd max_wal_senders. Behorend tot een cluster met karakteristieke Sending Servers, is het aantal processen dat verantwoordelijk is voor het verzenden van deze bestanden naar andere clusters, die altijd een waarde moet hebben die groter is dan het aantal clusters dat afhankelijk is van hun ontvangst.
WAL-bestanden kunnen worden opgeslagen voor verzending naar een cluster dat laat verbinding maakt, of dat problemen heeft gehad bij het ontvangen ervan, en die eerdere bestanden nodig hebben met betrekking tot de huidige tijd, met de eigenschap wal_keep_segments als specificatie voor hoeveel WAL-bestandssegmenten door een cluster moeten worden onderhouden.
Een replicatieslot is een functionaliteit waarmee het cluster WAL-bestanden kan opslaan die nodig zijn om een ander cluster van alle records te voorzien, met de optie max_replication_slots als eigenschap.
# default values
max_wal_senders = 10
wal_keep_segments = 0
max_replication_slots = 10
Als het de bedoeling is om de opslag van deze WAL-bestanden uit te besteden, kan een andere methode voor het verwerken van deze bestanden worden gebruikt, genaamd Continuous Archiving.
Continu archiveren
Dit concept stelt je in staat om de WAL-bestanden naar een specifieke locatie te leiden, met behulp van een Linux-programma, en twee variabelen die het pad van het bestand en zijn naam vertegenwoordigen, zoals %p en %f, respectievelijk.
Deze eigenschap is standaard uitgeschakeld, maar het gebruik ervan kan eenvoudig worden geïmplementeerd door de verantwoordelijkheid van een cluster voor het opslaan van dergelijke belangrijke bestanden terug te trekken, en kan worden toegevoegd aan het bestand postgresql.replication.conf.
P># 1. Creates a directory
mkdir ~/Documents/Severalnines/Archiving
# 2. Implementation on postgresql.replication.conf
archive_mode = on
archive_command = 'cp %p ~/Documents/Severalnines/Archiving/%f'
# 3. Starts the cluster
sudo systemctl start [email protected]
Na de clusterinitialisatie moeten sommige eigenschappen mogelijk worden gewijzigd en kan het opnieuw opstarten van het cluster vereist zijn. Sommige eigenschappen kunnen echter alleen opnieuw worden geladen, zonder dat een cluster volledig opnieuw moet worden opgestart.
Informatie over dergelijke onderwerpen kan worden verkregen via de opmerkingen in het bestand postgresql.conf, weergegeven als # (opmerking:voor wijziging moet opnieuw worden opgestart).
Als dit het geval is, is een eenvoudige manier om dit op te lossen het Linux-programma systemctl, dat eerder werd gebruikt om de cluster te starten, waarbij alleen de optie om opnieuw op te starten hoeft te worden genegeerd.
Als een volledige herstart niet vereist is, kan het cluster zelf zijn eigenschappen opnieuw toewijzen via een query die binnen zichzelf wordt uitgevoerd, maar als er meerdere clusters op dezelfde machine draaien, moet het een parameter doorgeven met de poortwaarde die aan het cluster is toegewezen op het besturingssysteem.
# Reload without restarting
sudo -H -u postgres psql -c ‘SELECT pg_reload_conf();’ -p 5433
In het bovenstaande voorbeeld vereist de eigenschap archive_mode een herstart, terwijl archive_command dat niet doet. Laten we na deze korte inleiding over dit onderwerp kijken hoe een replicacluster een back-up kan maken van deze gearchiveerde WAL-bestanden met behulp van Point In Time Recovery (PITR).
PostgreSQL-replicatie point-in-time herstel
Deze suggestieve naam stelt een cluster in staat om vanaf een bepaalde tijdsperiode terug te gaan naar zijn staat. Dit wordt gedaan via een eigenschap met de naam recovery_target_timeline, die een waarde in datumnotatie verwacht, zoals 22-08-2019 12:05 GMT, of de laatste toewijzing, die aangeeft dat herstel nodig is tot aan het laatste bestaande record.
Het programma pg_basebackup maakt, wanneer het draait, een kopie van een map met de gegevens van een cluster naar een andere locatie. Dit programma heeft de neiging om meerdere parameters te ontvangen, waaronder een -R, die een bestand met de naam recovery.conf aanmaakt in de gekopieerde map, die op zijn beurt niet hetzelfde is als de andere configuratiebestanden die eerder zijn gezien, zoals postgresql.conf .
Het bestand recovery.conf slaat de parameters op die zijn doorgegeven bij de uitvoering van het programma pg_basebackup, en het bestaan ervan is essentieel voor de implementatie van Streaming Replication, omdat het daarin is dat de omgekeerde bewerking naar de Continuous Archiving kan worden uitgevoerd.
# 1. Block name
replicate:
# 2. Removes the current data directory
rm -rf /var/lib/postgresql/11/$(replica)
# 3. Connects to primary cluster as user postgres
# 4. Copies the entire data directory
# 5. Creates the file recovery.conf
pg_basebackup -U postgres -d postgresql://localhost:$(primaryPort) -D /var/lib/postgresql/11/$(replica) -P -R
# 6. Inserts the restore_command property and its value
echo "restore_command = 'cp ~/Documents/Severalnines/Archiving/%f %p'" >> /var/lib/postgresql/11/$(replica)/recovery.conf
# 7. The same is done with recovery_target_timeline
echo "recovery_target_timeline = 'latest'" >> /var/lib/postgresql/11/$(replica)/recovery.conf
Dit replicatieblok dat hierboven is gespecificeerd, moet worden uitgevoerd door de postgres-gebruiker van het besturingssysteem om mogelijke conflicten te voorkomen met wie de eigenaar is van de clustergegevens, postgres of de root van de gebruiker.
Het replicacluster staat nog steeds, rijg het om de replicatie succesvol te starten, waarbij het replicaclusterproces genaamd pg_walreceiver interageert met het primaire cluster genaamd pg_walsender via een TCP-verbinding.
# 1. Executes the block ‘replicate’ by passing two parameters
sudo -H -u postgres make replicate replica=replica primaryPort=5433
# 2. Starts the cluster replica
sudo systemctl start [email protected]
Verificatie van de status van dit replicatiemodel, genaamd Streaming Replication, wordt uitgevoerd door een query die wordt uitgevoerd op het primaire cluster.
# 1. Checks the Streaming Replication created
sudo -H -u postgres psql -x -c ‘select * from pg_stat_replication;’ -p 5433
Conclusie
In deze blog hebben we laten zien hoe u asynchrone streamingreplicatie tussen twee PostgreSQL-clusters instelt. Onthoud echter dat er kwetsbaarheden bestaan in de bovenstaande code, het wordt bijvoorbeeld niet aanbevolen om de postgres-gebruiker te gebruiken om een dergelijke taak uit te voeren.
De replicatie van een cluster biedt verschillende voordelen wanneer het op de juiste manier wordt gebruikt en gemakkelijke toegang heeft tot de API's die met de clusters gaan communiceren.