TL;DR :Logisk replikering skickar rad-för-rad-ändringar, fysisk replikering skickar diskblocksändringar. Logisk replikering är bättre för vissa uppgifter, fysisk replikering för andra.
Observera att i PostgreSQL 12 (nuvarande vid tidpunkten för uppdatering) är logisk replikering stabil och pålitlig, men ganska begränsad. Använd fysisk replikering om du ställer den här frågan.
Strömmande replikering kan vara logisk replikering. Det hela är lite komplicerat.
WAL-frakt kontra streaming
Det finns två huvudsakliga sätt att skicka data från master till replika i PostgreSQL:
-
WAL-frakt eller kontinuerlig arkivering , där enskilda write-ahead-log-filer kopieras från
pg_xlog
medarchive_command
körs på mastern till någon annan plats. Ettrestore_command
konfigurerad i replikansrecovery.conf
körs på repliken för att hämta arkiven så att repliken kan spela upp WAL.Det här är vad som används för tidpunktsreplikering (PITR), som används som en metod för kontinuerlig säkerhetskopiering.
Ingen direkt nätverksanslutning krävs till huvudservern. Replikering kan ha långa förseningar, särskilt utan en
archive_timeout
uppsättning. WAL-frakt kan inte användas för synkron replikering. -
strömmande replikering , där varje ändring skickas till en eller flera replikservrar direkt över en TCP/IP-anslutning allt eftersom. Replikerna måste ha en direkt nätverksanslutning som mastern konfigurerat i deras
recovery.conf
sprimary_conninfo
alternativ.Strömmande replikering har liten eller ingen fördröjning så länge som repliken är tillräckligt snabb för att hänga med. Den kan användas för synkron replikering . Du kan inte använda strömmande replikering för PITR så det är inte mycket användbart för kontinuerlig säkerhetskopiering. Om du släpper ett bord på mastern, oj, det släpps också på replikerna.
De två metoderna har alltså olika syften.
Asynkron vs synkron streaming
Utöver det finns synkron och asynkron strömmande replikering:
-
I asynkron streaming-replikering replikerna tillåts falla efter mastern i tid när mastern är snabbare/upptagen. Om mastern kraschar kan du förlora data som inte har replikerats ännu.
Om den asynkrona repliken hamnar för långt bakom mastern, kan mastern kasta bort information som repliken behöver om
max_wal_size
(kallades tidigarewal_keep_segments) is too low and no slot is used, meaning you have to re-create the replica from scratch. Or the master's
pg_wal(was
pg_xlog) kan fyllas upp och stoppa mastern från att fungera tills diskutrymme frigörs ommax_wal_size
är för hög eller en plats används. -
I synkron replikering befälhavaren avslutar inte commit förrän en replik har bekräftat att den tagit emot transaktionen. Du förlorar aldrig data om mastern kraschar och du måste misslyckas över till en replik. Mastern kommer aldrig att kasta bort data som repliken behöver eller fylla upp sin xlog och få slut på diskutrymme på grund av replikförseningar. I utbyte kan det få mastern att sakta ner eller till och med sluta fungera om repliker har problem, och det har alltid en viss prestandapåverkan på mastern på grund av nätverkslatens.
När det finns flera repliker är bara en synkron åt gången. Se
synchronous_standby_names
.
Du kan inte ha synkron loggsändning.
Du kan faktiskt kombinera loggsändning och asynkron replikering för att skydda mot att behöva återskapa en replik om den hamnar för långt efter, utan att riskera att påverka mastern. Detta är en idealisk konfiguration för många distributioner, kombinerat med att övervaka hur långt repliken ligger bakom mastern för att säkerställa att den ligger inom acceptabla katastrofåterställningsgränser.
Logiskt kontra fysiskt
Ovanpå det vi har logiska kontra fysisk strömmande replikering, som introducerats i PostgreSQL 9.4:
-
I fysisk strömmande replikering ändringar skickas på nästan diskblocksnivå, som "vid offset 14 på disk sida 18 i relation 12311, skrev tupel med hexvärde 0x2342beef1222...".
Fysisk replikering skickar allt :innehållet i varje databas i PostgreSQL-installationen, alla tabeller i varje databas. Den skickar indexposter, den skickar helt nya tabelldata när du
VACUUM FULL
, den skickar data för transaktioner som rullas tillbaka, etc. Så den genererar mycket "brus" och skickar mycket överflödig data. Det kräver också att repliken är helt identisk, så du kan inte göra något som skulle kräva en transaktion, som att skapa tillfälliga eller ologgade tabeller. Att fråga repliken fördröjer replikeringen, så långa frågor om repliken måste avbrytas.
I utbyte är det enkelt och effektivt att tillämpa ändringarna på repliken, och repliken är tillförlitligt exakt densamma som mastern. DDL replikeras transparent, precis som allt annat, så det kräver ingen speciell hantering. Det kan också streama stora transaktioner när de inträffar, så det är liten fördröjning mellan commit på mastern och commit på repliken även för stora förändringar.
Fysisk replikering är mogen, väl testad och allmänt antagen.
- logisk strömmande replikering , nytt i 9.4, skickar ändringar på en högre nivå och mycket mer selektivt.
Den replikerar endast en databas åt gången. Den skickar bara radändringar och endast för genomförda transaktioner, och den behöver inte skicka vakuumdata, indexändringar etc. Den kan selektivt skicka data endast för vissa tabeller i en databas. Detta gör logisk replikering mycket mer bandbreddseffektiv.
Att arbeta på en högre nivå innebär också att du kan göra transaktioner på replikdatabaserna. Du kan skapa tillfälliga och ologgade tabeller. Även vanliga bord, om du vill. Du kan använda främmande dataomslag, vyer, skapa funktioner, vad du vill. Det finns ingen anledning att avbryta frågor om de körs för länge heller.
Logisk replikering kan också användas för att bygga flermasterreplikering i PostgreSQL, vilket inte är möjligt med fysisk replikering.
I utbyte kan det dock (för närvarande) inte streama stora transaktioner när de händer. Det får vänta tills de binder sig. Så det kan vara en lång fördröjning mellan en stor transaktion som genomförs på mastern och den appliceras på repliken.
Den spelar om transaktioner strikt i commit-ordning, så små snabba transaktioner kan fastna bakom en stor transaktion och bli försenade ett tag.
DDL hanteras inte automatiskt. Du måste själv hålla tabelldefinitionerna synkroniserade mellan master och replik, eller så måste applikationen som använder logisk replikering ha sina egna faciliteter för att göra detta. Det kan vara komplicerat att få det här rätt.
Själva appliceringsprocessen är mer komplicerad än att "skriva några bytes där jag är tillsagd att göra det". Det tar också mer resurser på repliken än vad fysisk replikering gör.
Aktuella logiska replikeringsimplementeringar är inte mogna eller allmänt använda, eller särskilt lätta att använda.
För många alternativ, berätta vad jag ska göra
Puh. Komplicerat, va? Och jag har inte ens kommit in på detaljerna om fördröjd replikering, slots, max_wal_size
, tidslinjer, hur marknadsföring fungerar, Postgres-XL, BDR och multimaster, etc.
Så vad ska du göra ?
Det finns inget rätt svar. Annars skulle PostgreSQL bara stödja det på ett sätt. Men det finns några vanliga användningsfall:
För säkerhetskopiering och katastrofåterställning använd pgbarman
att göra grundläggande säkerhetskopior och behålla WAL åt dig, vilket ger enkel att hantera kontinuerlig säkerhetskopiering. Du bör fortfarande ta periodisk pg_dump
säkerhetskopior som extra försäkring.
För hög tillgänglighet utan risk för dataförlust använd strömmande synkron replikering.
För hög tillgänglighet med låg risk för dataförlust och bättre prestanda du bör använda asynkron streaming replikering. Antingen har WAL-arkivering aktiverat för reserv eller använd en replikeringsplats. Övervaka hur långt repliken ligger bakom mastern med hjälp av externa verktyg som Icinga.
Referenser
- kontinuerlig arkivering och PITR
- hög tillgänglighet, lastbalansering och replikering
- replikeringsinställningar
- recovery.conf
- pgbarman
- repmgr
- wiki:replikering, klustring och anslutningspoolning