PostgreSQL kan fungera separat på flera maskiner med samma datastruktur, vilket gör applikationens beständighetslager mer motståndskraftig och förberedd för någon oväntad händelse som kan äventyra tjänstens kontinuitet.
Idén bakom detta är att förbättra systemets svarstid genom att distribuera förfrågningarna i ett "Round Robin"-nätverk där varje närvarande nod är ett kluster. I denna typ av konfiguration är det inte viktigt för vilken förfrågningar som ska levereras för att behandlas, eftersom svaret alltid skulle vara detsamma.
I den här bloggen kommer vi att förklara hur man replikerar ett PostgreSQL-kluster med hjälp av verktygen som tillhandahålls i programinstallationen. Den version som används är PostgreSQL 11.5, den nuvarande stabila, allmänt tillgängliga versionen för operativsystemet Debian Buster. För exemplen i den här bloggen antas det att du redan är bekant med Linux.
PostgreSQL-program
Inte i katalogen /usr/bin/ finns programmet som ansvarar för att hantera klustret.
# 1. Lists the files contained in the directory
# 2. Filters the elements that contain 'pg_' in the name
ls /usr/bin/ | grep pg_
Aktiviteter som utförs genom dessa program kan utföras sekventiellt eller till och med i kombination med andra program. Att köra ett block av dessa aktiviteter genom ett enda kommando är möjligt tack vare ett Linux-program som finns i samma katalog, kallat make.
För att lista de kluster som finns använd programmet pg_lsclusters. Du kan också använda make för att köra den. Dess arbete beror på en fil som heter Makefile, som måste finnas i samma katalog där kommandot körs.
# 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
Definitionen av ett block visas nedan, med namnet ls och ett enda program som ska köras, pg_lsclusters.
# 1. Block name
ls:
# 2. Program to be executed
pg_lsclusters
Filen Makefile kan innehålla flera block, och var och en kan köra så många program som du behöver, och till och med ta emot parametrar. Det är absolut nödvändigt att raderna som hör till ett exekveringsblock är korrekta, genom att använda tabeller för indrag istället för mellanslag.
Användningen av make för att köra programmet pg_lsclusters görs genom att använda kommandot make ls.
# 1. Executes pg_lsclusters
make ls
Resultatet som erhölls i en nyligen genomförd PostgreSQL-installation ger ett enda kluster som kallas main, allokerat på port 5432 i operativsystemet. När programmet pg_createcluster används, allokeras en ny port till det nya skapade klustret, med värdet 5432 som startpunkt, tills en annan hittas i stigande ordning.
Write Ahead Logging (WAL)
Denna replikeringsprocedur består av att göra en säkerhetskopia av ett fungerande kluster som fortsätter att ta emot uppdateringar. Om detta görs på samma maskin går dock många av fördelarna med denna teknik förlorade.
Att skala ett system horisontellt säkerställer större tillgänglighet för tjänsten, som om det skulle uppstå hårdvaruproblem skulle det inte göra någon större skillnad eftersom det finns andra maskiner som är redo att ta på sig arbetsbördan.
WAL är termen som används för att representera en intern komplex algoritm till PostgreSQL som säkerställer integriteten för de transaktioner som görs på systemet. Däremot måste endast ett enskilt kluster ha ansvaret för att komma åt det med skrivbehörighet.
Arkitekturen har nu tre distinkta typer av kluster:
- En primär med ansvar för att skriva till WAL;
- En replik redo att ta över den primära posten;
- Övriga andra repliker med WAL-läsplikt.
Skrivoperationer är alla aktiviteter som är avsedda att ändra datastrukturen, antingen genom att ange nya element eller uppdatera och ta bort befintliga poster.
PostgreSQL-klusterkonfiguration
Varje kluster har två kataloger, en som innehåller dess konfigurationsfiler och en annan med transaktionsloggarna. Dessa finns i /etc/postgresql/11/$(cluster) respektive /var/lib/postgresql/11/$(cluster) (där $(cluster) är namnet på klustret).
Filen postgresql.conf skapas omedelbart efter att klustret har skapats genom att köra programmet pg_createcluster, och egenskaperna kan ändras för anpassning av ett kluster.
Att redigera den här filen direkt rekommenderas inte eftersom den innehåller nästan alla egenskaper. Deras värden har kommenterats bort, med symbolen # i början av varje rad, och flera andra rader har kommenterats ut med instruktioner för att ändra egenskapsvärdena.
Det är möjligt att lägga till ytterligare en fil som innehåller de önskade ändringarna, redigera helt enkelt en enskild egenskap som heter include, ersätt standardvärdet #include ='' med include ='postgresql.replication.conf'.
Innan du startar klustret behöver du närvaron av filen postgresql.replication.conf i samma katalog där du hittar den ursprungliga konfigurationsfilen, kallad 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
Användningen av --data-checksums vid skapandet av klustret ger en högre nivå av integritet till data, vilket kostar lite prestanda men är mycket viktigt för att undvika korruption av filerna när överförs från ett kluster till ett annat.
Procedurerna som beskrivs ovan kan återanvändas för andra kluster, genom att helt enkelt skicka ett värde till $(cluster) som en parameter i körningen av programmet make.
# 1. Executes the block 'create' by passing a parameter
sudo make create cluster=primary
Nu när en kort automatisering av uppgifterna har etablerats, är det som återstår att göra definitionen av filen postgresql.replication.conf enligt behovet för varje kluster.
replikering på PostgreSQL
Två sätt att replikera ett kluster är möjliga, det ena är komplett, det andra involverar hela klustret (kallad Streaming Replication) och ett annat kan vara partiellt eller fullständigt (kallat Logical Replication).
Inställningarna som måste anges för ett kluster delas in i fyra huvudkategorier:
- Master Server
- Standby-servrar
- Skicka servrar
- Prenumeranter
Som vi såg tidigare är WAL en fil som innehåller transaktionerna som görs på klustret, och replikeringen är överföringen av dessa filer från ett kluster till ett annat.
Inuti inställningarna som finns i filen postgresql.conf kan vi se egenskaper som definierar beteendet hos klustret i förhållande till WAL-filerna, såsom storleken på dessa filer.
# default values
max_wal_size = 1GB
min_wal_size = 80MB
En annan viktig egenskap som heter max_wal_senders. Att tillhöra ett kluster med karakteristiska sändningsservrar är mängden processer som är ansvariga för att skicka dessa filer till andra kluster, som alltid måste ha ett värde mer än antalet kluster som beror på deras mottagande.
WAL-filer kan lagras för överföring till ett kluster som ansluter sent, eller som har haft problem med att ta emot det, och som behöver tidigare filer i förhållande till aktuell tid, med egenskapen wal_keep_segments som specifikation för hur många WAL-filsegment som ska underhållas av ett kluster.
En replikeringsplats är en funktion som gör att klustret kan lagra WAL-filer som behövs för att förse ett annat kluster med alla poster, med alternativet max_replication_slots som egenskap.
# default values
max_wal_senders = 10
wal_keep_segments = 0
max_replication_slots = 10
När avsikten är att lägga ut lagringen av dessa WAL-filer på entreprenad, kan en annan metod för att bearbeta dessa filer användas, kallad Kontinuerlig arkivering.
Kontinuerlig arkivering
Det här konceptet låter dig dirigera WAL-filerna till en specifik plats med hjälp av ett Linux-program och två variabler som representerar sökvägen till filen och dess namn, såsom %p och %f, respektive.
Denna egenskap är inaktiverad som standard, men dess användning kan enkelt implementeras genom att ta bort ansvaret för ett kluster från att lagra sådana viktiga filer och kan läggas till i filen postgresql.replication.conf.
# 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]
Efter klusterinitieringen kan vissa egenskaper behöva ändras och en omstart av kluster kan krävas. Vissa egenskaper kan dock bara laddas om, utan att en fullständig omstart av ett kluster behövs.
Information om sådana ämnen kan erhållas genom kommentarerna i filen postgresql.conf, som visas som # (notera:ändring kräver omstart).
Om detta är fallet är ett enkelt sätt att lösa med Linux-programmet systemctl, som tidigare användes för att starta klustret, och behöver bara åsidosätta alternativet att starta om.
När en fullständig omstart inte krävs kan klustret självt omtilldela sina egenskaper genom en frågekörning inom sig själv, men om flera kluster körs på samma dator kommer det att krävas att skicka en parameter som innehåller portvärdet som klustret är tilldelat på operativsystemet.
# Reload without restarting
sudo -H -u postgres psql -c ‘SELECT pg_reload_conf();’ -p 5433
I exemplet ovan kräver egenskapen archive_mode en omstart, medan archive_command inte gör det. Efter denna korta introduktion till detta ämne, låt oss titta på hur ett replikkluster kan säkerhetskopiera dessa arkiverade WAL-filer med hjälp av Point In Time Recovery (PITR).
PostgreSQL-replikeringspunkt-i-tid-återställning
Detta suggestiva namn tillåter ett kluster att gå tillbaka till sitt tillstånd från en viss tidsperiod. Detta görs genom en egenskap som heter recovery_target_timeline, som förväntar sig att få ett värde i datumformat, till exempel 2019-08-22 12:05 GMT, eller den senaste tilldelningen, som informerar om behovet av en återställning upp till den senaste befintliga posten.
Programmet pg_basebackup när det körs gör en kopia av en katalog som innehåller data från ett kluster till en annan plats. Det här programmet tenderar att ta emot flera parametrar, som är en av dem -R, som skapar en fil med namnet recovery.conf i den kopierade katalogen, som i sin tur inte är densamma som innehåller de andra konfigurationsfilerna som tidigare setts, såsom postgresql.conf .
Filen recovery.conf lagrar parametrarna som skickades i körningen av programmet pg_basebackup, och dess existens är avgörande för implementeringen av Streaming Replikering, eftersom det är inom den som den omvända operationen till den kontinuerliga arkiveringen kan utföras.
# 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
Detta replikeringsblock som anges ovan måste köras av operativsystemets postgres-användare för att undvika potentiella konflikter med vem som är ägare till klusterdata, postgres eller användarroten.
Replikaklustret står fortfarande och bastar det för att framgångsrikt starta replikeringen, och replikklusterprocessen som kallas pg_walreceiver interagerar med det primära klustret som kallas pg_walsender över en TCP-anslutning.
# 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]
Verifiering av tillståndet för denna replikeringsmodell, kallad Streaming Replication, utförs av en fråga som körs på det primära klustret.
# 1. Checks the Streaming Replication created
sudo -H -u postgres psql -x -c ‘select * from pg_stat_replication;’ -p 5433
Slutsats
I den här bloggen visade vi hur man ställer in asynkron streaming-replikering mellan två PostgreSQL-kluster. Kom dock ihåg att det finns sårbarheter i koden ovan, till exempel rekommenderas inte att använda postgres-användaren för att utföra en sådan uppgift.
Replikeringen av ett kluster ger flera fördelar när det används på rätt sätt och har enkel tillgång till API:erna som kommer att interagera med klustren.