Postgres kommer med fysiske og logiske replikeringsfunktioner. Læs videre for at lære mere om forskellige aspekter af fysisk replikation.
Fysisk replikering
Fysiske replikeringsmetoder bruges til at vedligeholde en fuld kopi af alle data fra en enkelt klynge (i Postgres, en klynge er et sæt databaser, der styres af en enkelt Postgres hovedserverproces kaldet en postmaster ), typisk på en anden maskine. Kildemaskinen kaldes den primære i Postgres-jargon, og destinationen kaldes standby .
Varme, varme og "kolde" standbyer
En standby-server, der holdes så opdateret som muligt med den primære inrealtid og tillader klienter at udføre skrivebeskyttede transaktioner, kaldes enhot standby, eller mere populært en læst replika . Hot standbys blev føjet til Postgres i version 9, før hvilken der kun var varme standby. En varm standby ligner en varm standby, bortset fra at den ikke lader klienter oprette forbindelse til den.
(Bortset:Hot standbys kan ikke udføre forespørgsler, der skaber midlertidige tabeller. Dette er en Postgres-begrænsning.)
En "kold" standby (ikke et officielt udtryk) er normalt en standby-server, der ikke starter før en failover. Da den kolde standby ikke er oppe at køre, er det muligt, at den ved opstart muligvis først skal anvende afventende ændringer, før den kan begynde at acceptere klientforbindelser.
WAL-filer
I det normale forløb genererer en PostgreSQL-server en bestilt serie af WAL-poster (write ahead log). Disse er dybest set en log over ændringer, svarende til Redis' AOF eller MySQL's binlog. Grundlæggende er fysisk replikering transporten af disse poster til en anden maskine og at få den anden postmaster, som kører der, til at acceptere og anvende disse poster i sin lokale database.
WAL-poster er delt i lige store (normalt 16 MB) filer kaldetWAL-segmenter eller bare WAL-filer . Disse filer oprettes i en mappe kaldet pg_wal
under klyngedatabiblioteket (pg_wal
blev kaldt pg_xlog
i Postgres-versioner før 10). Gamle WAL-filer kasseres, når de ikke længere er nødvendige (og også baseret på et par konfigurationsparametre).
Gendannelsestilstand
Postmesteren kan startes op i en tilstand kaldet gendannelsestilstand , ved at placere en gyldig konfigurationsfil kaldet recovery.conf i klyngedatamappen. I gendannelsestilstand vil Postgres kun importere og anvende WAL-filer, der er genereret af en primær server, og vil i sig selv ikke generere nogen WAL-filer. Varme og hotstandby-servere kører i gendannelsestilstand.
Når den startes op i gendannelsestilstand, vil Postgres først prøve at importere alle tilgængelige WAL-filer i et arkiv (mere om dette nedenfor). Når arkivet ikke har flere WAL-filer at tilbyde, forsøger det at importere alle filer, der ligger omkring inits pg_wal
vejviser. Når også disse er færdige, hvis en primær forbindelse er konfigureret og standby_modeset til on
i recovery.conf vil Postgres oprette forbindelse til den primære og trække og anvende nye WAL-poster, efterhånden som de bliver oprettet ved den primære.
Logforsendelse
Forestil dig at have en udløser, der vil blive aktiveret på den primære server, hver gang en ny WAL-fil oprettes. Denne udløser kan derefter kopiere den nye WAL-fil til en anden maskine ved at sige rsync
, og placer den i pg_wal
mappe for en postmaster, der kører i gendannelsestilstand. Kan du gøre en standby som denne?
Svaret er ja, og dette var faktisk standardpraksis, før streamingreplikering blev tilføjet i Postgres v9. Denne praksis kaldes logforsendelse .
Udløseren er et shell-script, der kan konfigureres ved hjælp af archive_command. Navnet og stien til WAL-filen kan videregives til scriptet.
WAL-arkivering
I stedet for at rsynkronisere over WAL-filen, lad os sige, at vi kopierer den til en S3-bucketor, en NFS-monteret mappe, som også er tilgængelig fra standby-maskinen. Denne delte placering vil nu indeholde alle de WAL-filer, der er genereret af den primære. bliver et arkiv , og processen med at gemme WAL-filer i arkivet kaldes kontinuerlig arkivering eller blot WAL-arkivering .
Det omvendte af denne operation – hentning af WAL-filer fra arkivet til arecovery-mode Postgres – kan konfigureres ved hjælp af restore_command. Svarende til archive_command
, dette er også stien til et shell-script. Postmasteren, der kører i gendannelsestilstand, ved hvilken WAL-fil den vil have. Navnet på filen kan videregives til scriptet.
Som et eksempel er her arkiverings- og gendannelseskommandoer til lagring og hentning af WAL-filer til og fra en S3-bøtte:
archive_command = 's3cmd put %p s3://BUCKET/path/%f' # in postgresql.conf
restore_command = 's3cmd get s3://BUCKET/path/%f %p' # in recovery.conf
Ved opstart i gendannelsestilstand, hvis restore_command
er konfigureret, vil Postgres først prøve at hente WAL-filer fra arkivet.
pg_standby
I gendannelsestilstand ved og kan Postgres ikke på forhånd, hvor mange WAL-filer, der er blevet genereret indtil videre. Hvis restore_command er konfigureret, vil Postgres gentagne gange påkalde den med progressive WAL-filnavne (navnene er i forudsigelig rækkefølge), indtil kommandoen returnerer en fejl.
For eksempel var gendannelseskommandoen i stand til at tilfredsstille anmodningerne om WAL-filer000000010000000000000001
gennem 00000001000000000000001A
men mislykkes for00000001000000000000001B
da den ikke blev fundet i arkivplaceringen. I mangel af WAL-filer fra andre kilder, vil Postgres antage, at WAL-filen 00000001000000000000001B
er endnu ikke genereret af den primære, og vil afslutte gendannelsen efter anvendelse af 00000001000000000000001A
.
Overvej, hvad der sker, hvis gendannelseskommandoen ventede på filen00000001000000000000001B
at være tilgængelig, i stedet for at afslutte med fejl, da den ikke blev fundet. Postgres vil fortsætte med at vente på gendannelseskommando og vil derfor fortsætte med at være i gendannelsestilstand.
Dette er en gyldig konfiguration og en gyldig måde at opsætte en varm standby på.
Postgres leveres med en kommando kaldet pg_standby, som kan bruges til at opsætte en varm standby på denne måde, så længe arkivet er en mappe.pg_standby
vil vente på, at en fil bliver tilgængelig, hvis den ikke kan findes.
Arkiver og gendan kommandoer ved hjælp af pg_standby vil se sådan ud:
archive_command = 'cp %p /some/path/%f' # in postgresql.conf
restore_command = 'pg_standby /some/path %f %p' # in recovery.conf
Streamende replikering
Efter behandling af arkiverede WAL-filer samt filer i pg_wal
mappe, kan Postgres oprette forbindelse til en primær server over netværket og gentagne gange hente og anvende nye WAL-filer, efterhånden som de oprettes. Denne funktion, tilføjet i Postgres 9, kaldes streaming replikering .
Den primære server, der skal oprettes forbindelse til, kan angives i filen recovery.conf:
# recovery.conf
standby_mode = on
primary_conninfo = 'host=10.0.1.10 user=repl password=p@ssw0rd'
Hot Standby
Som standard, når Postgres er i gendannelsestilstand, accepterer Postgres ikke klientforbindelser og afviser dem med fejlmeddelelser "databasesystemet er i gendannelsestilstand". Ved at tilføje linjen hot_standby = on
i recovery.conf kan du lave Postgresaccept klientforbindelser og tillade dem at udføre skrivebeskyttede transaktioner:
# recovery.conf
hot_standby = on
Der er normalt ingen grund til at slå hot_standby fra.
PostgreSQL-dokumentet har flere oplysninger om opsætning og drift af en standby i "hot standby"-tilstand.
replikeringspladser
Replikationsslots blev introduceret i Postgres 9.4. De er en mekanisme til nøjagtigt og holdbart at holde styr på, hvor langt en standby halter bagefter den primære. Dette gør det muligt for den primære at sikre, at WAL-filer, der stadig er nødvendige for, at standbyen kan indhente, ikke slettes.
Før replikationsslots var det ikke muligt for den primære at bestemme dette, og du ville ende i situationer, hvor en standby blev efterladt strandet, fordi en WAL-fil, den havde brug for, var blevet slettet af den primære. Selvfølgelig kan WAL-arkiver løse dette problem. Uden et WAL-arkiv var den eneste mulighed dog at genopbygge standbyen fra en ny backup.
Du kan læse mere om replikeringsslots her.
Trin til opsætning af en varm standby
Lad os tage et kig på de nødvendige trin for at konfigurere en varm standby for en eksisterende primær.
1. Opret replikeringsbruger
Først skal vi bruge en bruger til standby for at oprette forbindelse som:
$ psql -p 6000
psql (11.2 (Debian 11.2-1.pgdg90+1))
Type "help" for help.
postgres=# CREATE USER repluser REPLICATION PASSWORD 'p@ssw0rd';
CREATE USER
Og de tilsvarende ændringer i pg_hba.conf
:
# TYPE DATABASE USER ADDRESS METHOD
host replication repluser standby-ip/32 md5
# (replace standby-ip)
Du kan selvfølgelig bruge enhver standardgodkendelsesmekanisme af PostgreSQL. Brugeren skal have replikerings- og login-rettigheder og kræver ikke adgang til nogen specifik database.
Sørg for at genindlæse den primære server, for at ændringerne til pg_hba.conf træder i kraft.
2. Tag en sikkerhedskopi
Standbyen skal starte fra en backup af den primære. Du kan og bør gøre dette ved at bruge pg_basebackup
med en ny replikeringsplads:
pg_basebackup -h primary-ip -p 6000 -U repluser -C -S slot_standby1 -R -D standby
Dette forbinder til den primære på primary-ip:6000
med den bruger, vi lige har oprettet, og tager en sikkerhedskopi af den til mappen standby
. En ny replikeringspladsslot_standby1
er oprettet.
3. Tilføj recovery.conf I standby
Vi bruger denne slot som vores standby-replikeringsplads, så der er kontinuitet fra backup'en.
Vi havde spurgt pg_basebackup
for at oprette en recovery.conf
for os ovenfor ("-R"-mulighed). Lad os se på det:
$ cat standby/recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=repluser password=''p@ssw0rd'' host=primary-ip port=6000 sslmode=prefer sslcompression=0 krbsrvname=postgres target_session_attrs=any'
primary_slot_name = 'slot_standby1'
Det er faktisk ret godt, og vi behøver ikke at ændre det yderligere. Lad os bare bringe standby op nu:
o$ pg_ctl -D standby -l log_standby -o --port=6001 start
waiting for server to start.... done
server started
postgres@stg1:/tmp/demo$ cat log_standby
2019-06-19 09:17:50.032 UTC [21733] LOG: listening on IPv4 address "127.0.0.1", port 6001
2019-06-19 09:17:50.034 UTC [21733] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.6001"
2019-06-19 09:17:50.067 UTC [21734] LOG: database system was interrupted; last known up at 2019-06-19 09:12:05 UTC
2019-06-19 09:17:50.111 UTC [21734] LOG: entering standby mode
2019-06-19 09:17:50.119 UTC [21734] LOG: redo starts at 0/2000028
2019-06-19 09:17:50.120 UTC [21734] LOG: consistent recovery state reached at 0/20000F8
2019-06-19 09:17:50.120 UTC [21733] LOG: database system is ready to accept read only connections
2019-06-19 09:17:50.138 UTC [21739] LOG: started streaming WAL from primary at 0/3000000 on timeline 1
Og det er det! Logfilen angiver, at streaming-replikering er oppe og køre. Du skulle nu være i stand til at oprette forbindelse til standby ved port 6001, køre skrivebeskyttede forespørgsler og se ændringer blive replikeret fra den primære mere eller mindre i realtid.
Næste trin
PostgreSQLdocs er et godt sted at begynde at grave yderligere i alle replikeringsrelaterede funktioner i Postgres. Du vil gerne se nærmere på emner som forsinket replikering, kaskadereplikering, synkrone standbyer og mere.
Selvom Postgres kommer med et imponerende sæt funktioner, er der stilluse-cases, der ikke understøttes. Denne Postgres wikiside har en liste over tredjepartsværktøjer, der giver yderligere replikeringsrelateret funktionalitet.