sql >> Databasteknik >  >> RDS >> PostgreSQL

Fysiska replikeringsmekanismer i PostgreSQL

Postgres kommer med fysiska och logiska replikeringsfunktioner. Läs vidare för att lära dig mer om olika aspekter av fysisk replikering.

Fysisk replikering

Fysiska replikeringsmetoder används för att upprätthålla en fullständig kopia av hela data från ett enda kluster (i Postgres, ett kluster är en uppsättning databaser som hanteras av en enda Postgres huvudserverprocess som kallas en postmaster ), vanligtvis på en annan maskin. Källmaskinen kallas primär i Postgres jargong, och destinationen kallas standby .

Varma, varma och "kalla" standbylägen

En standby-server som hålls så uppdaterad som möjligt med den primära inrealtiden och tillåter klienter att utföra skrivskyddade transaktioner kallas enhot standby, eller mer populärt en läs replik . Hot standbys lades till Postgres i version 9, innan det bara fanns varma standby. En varm standby liknar en varm standby, förutom att den inte låter klienter ansluta till den.

(Av sidan:Hot standbys kan inte utföra frågor som skapar tillfälliga tabeller. Detta är en Postgres-begränsning.)

En "kall" standby (inte en officiell term) är vanligtvis en standby-server som inte startar förrän en failover. Eftersom kall standby inte är igång, är det möjligt att det vid start först måste tillämpa väntande ändringar innan det kan börja acceptera klientanslutningar.

WAL-filer

Under det normala driftförloppet genererar en PostgreSQL-server en beställd serie av WAL-poster (write ahead log). Dessa är i grunden en logg över ändringar, liknande Redis AOF eller MySQL:s binlog. I grunden är fysisk replikering transporten av dessa poster till en annan maskin, och att få den andra postmästaren som kör där att acceptera och tillämpa dessa poster i sin lokala databas.

WAL-poster är uppdelade i lika stora (vanligtvis 16 MB) filer som kallasWAL-segment eller bara WAL-filer . Dessa filer skapas i en katalog som heter pg_wal under klusterdatakatalogen (pg_wal kallades pg_xlog i Postgres-versioner före 10). Gamla WAL-filer kasseras när de inte längre behövs (och även baserat på ett par konfigurationsparametrar).

Återställningsläge

Postmastern kan startas i ett läge som kallas återställningsläge , genom att placera en giltig konfigurationsfil som heter recovery.conf i klusterdatakatalogen. I återställningsläge kommer Postgres endast att importera och tillämpa WAL-filer som genererats av en primär server, och i sig själv kommer inte att generera några WAL-filer. Varma och hotstandby-servrar körs i återställningsläge.

När Postgres startas upp i återställningsläget kommer Postgres först att försöka importera alla tillgängliga WAL-filer i ett arkiv (mer om detta nedan). När arkivet inte har några fler WAL-filer att erbjuda, försöker det importera alla filer som ligger runt inits pg_wal katalog. När även dessa är klara, om en primär anslutning är konfigurerad och standby_modeset till on i recovery.conf kommer Postgres att ansluta till den primära och dra och tillämpa nya WAL-poster allt eftersom de skapas vid den primära.

Loggsändning

Föreställ dig att ha en utlösare som kommer att anropas på den primära servern när en ny WAL-fil skapas. Denna utlösare kan sedan kopiera den nya WAL-filen till en annan maskin med säg rsync , och placera den i pg_wal katalog för en postmaster som körs i återställningsläge. Kan du göra ett sånt här standbyläge?

Svaret är ja, och detta var faktiskt standardpraxis innan streamingreplikering lades till i Postgres v9. Denna praxis kallas loggfrakt .

Utlösaren är ett skalskript som kan konfigureras med archive_command. Namnet och sökvägen till WAL-filen kan skickas till skriptet.

WAL-arkivering

Istället för att rsynka över WAL-filen, låt oss säga att vi kopierar den till en S3-bucketor en NFS-monterad katalog som också är tillgänglig från standby-maskinen. Den här delade platsen kommer nu att innehålla alla WAL-filer som genereras av den primära. blir ett arkiv , och processen att lagra WAL-filer i arkivet kallas kontinuerlig arkivering eller helt enkelt WAL-arkivering .

Det omvända till denna operation – att hämta WAL-filer från arkivet till arecovery-mode Postgres – kan konfigureras med hjälp av restore_command. Liknande archive_command , även detta är vägen till ett skalskript. Postmastern som körs i återställningsläge vet vilken WAL-fil den vill ha. Namnet på filen kan skickas till skriptet.

Som ett exempel, här är arkiverings- och återställningskommandon för att lagra och hämta WAL-filer till och från en S3-hink:

archive_command = 's3cmd put %p s3://BUCKET/path/%f' # in postgresql.conf
restore_command = 's3cmd get s3://BUCKET/path/%f %p' # in recovery.conf

Vid start i återställningsläge, om restore_command är konfigurerad, kommer Postgres först att försöka hämta WAL-filer från arkivet.

pg_standby

I återställningsläge vet och kan inte Postgres i förväg veta hur många WAL-filer som har genererats hittills. Om restore_command är konfigurerat kommer Postgres upprepade gånger att anropa det med progressiva WAL-filnamn (namnen är i förutsägbar sekvens) tills kommandot returnerar ett fel.

Till exempel kunde återställningskommandot tillgodose förfrågningarna om WAL-filer000000010000000000000001 genom 00000001000000000000001A men misslyckas för00000001000000000000001B eftersom den inte hittades på arkivplatsen. I avsaknad av WAL-filer från andra källor kommer Postgres att anta att WAL-filen 00000001000000000000001B har ännu inte genererats av den primära och kommer att slutföra återställningen efter applicering av 00000001000000000000001A .

Fundera på vad som händer om återställningskommandot väntar på filen00000001000000000000001B vara tillgänglig istället för att avsluta med fel eftersom den inte hittades. Postgres kommer att fortsätta att vänta på återställningskommandot och kommer därför att fortsätta att vara i återställningsläge.

Detta är en giltig konfiguration och ett giltigt sätt att ställa in ett varmt standbyläge.

Postgres levereras med kommandot pg_standby, som kan användas för att ställa in en varm standby på detta sätt, så länge som arkivet är en katalog.pg_standby väntar på att en fil blir tillgänglig om den inte kan hittas.

Arkivera och återställa kommandon med pg_standby kommer att se ut så här:

archive_command = 'cp %p /some/path/%f'         # in postgresql.conf
restore_command = 'pg_standby /some/path %f %p' # in recovery.conf

Streamande replikering

Efter bearbetning av arkiverade WAL-filer samt filer i pg_wal katalog, Postgres kan ansluta till en primär server över nätverket och upprepade gånger hämta och tillämpa nya WAL-filer när de skapas. Denna funktion, som läggs till i Postgres 9, kallas strömmande replikering .

Den primära servern att ansluta till kan anges 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, i återställningsläge, accepterar Postgres inte klientanslutningar, och avvisar dem med felmeddelanden "databassystemet är i återställningsläge". Genom att lägga till raden hot_standby = on i recovery.conf kan du göra Postgresaccept-klientanslutningar och tillåta dem att utföra skrivskyddade transaktioner:

# recovery.conf
hot_standby = on

Det finns vanligtvis ingen anledning att stänga av hot_standby.

PostgreSQL-dokumentet har mer information om att ställa in och köra ett standbyläge i "hot standby"-läget.

replikeringsplatser

Replikationsplatser introducerades i Postgres 9.4. De är en mekanism för att noggrant och hållbart hålla reda på hur långt ett standbyläge släpar efter det primära. Detta gör att den primära kan säkerställa att WAL-filer som fortfarande behövs för att standby-läget ska hinna inte raderas.

Innan replikeringsplatserna var det inte möjligt för den primära att avgöra detta, och du skulle hamna i situationer där en standby lämnades strandad eftersom en WAL-fil den behövde hade raderats av den primära. Naturligtvis kan WAL-arkiv fixa det här problemet. Utan ett WAL-arkiv var det enda alternativet att bygga om standby-läget från en ny säkerhetskopia.

Du kan läsa mer om replikeringsplatser här.

Steg för att ställa in en Hot Standby

Låt oss ta en titt på stegen som behövs för att ställa in en varm standby för en befintlig primär.

1. Skapa replikeringsanvändare

Först behöver vi en användare för vänteläget för att ansluta 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

Och motsvarande ändringar i pg_hba.conf :

# TYPE  DATABASE        USER          ADDRESS        METHOD
host    replication     repluser      standby-ip/32  md5
# (replace standby-ip)

Du kan naturligtvis använda vilken standardautentiseringsmekanism som helst för PostgreSQL. Användaren måste ha replikerings- och inloggningsrättigheter och kräver inte åtkomst till någon specifik databas.

Se till att ladda om den primära servern för att ändringarna till pg_hba.conf ska träda i kraft.

2. Ta en säkerhetskopia

Vänteläget måste starta från en säkerhetskopia av den primära. Du kan och bör göra detta med pg_basebackup med en ny replikeringsplats:

pg_basebackup -h primary-ip -p 6000 -U repluser -C -S slot_standby1 -R -D standby

Denna ansluter till den primära på primary-ip:6000 med användaren vi just skapade och tar en säkerhetskopia av den till katalogen standby . En ny replikeringsplatsslot_standby1 skapas.

3. Lägg till recovery.conf i vänteläge

Vi kommer att använda denna plats som vår standby-replikeringsplats, så att det finns kontinuitet från säkerhetskopian.

Vi hade frågat pg_basebackup för att skapa en recovery.conf för oss ovan ("-R"-alternativet). Låt oss ta en titt 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 är faktiskt ganska bra, och vi behöver inte ändra det ytterligare. Låt oss helt enkelt ta upp vänteläget 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

Och det är allt! Loggfilen indikerar att strömmande replikering är igång. Du bör nu kunna ansluta till vänteläget vid port 6001, köra skrivskyddade frågor och se ändringar replikeras från den primära mer eller mindre i realtid.

Nästa steg

PostgreSQLdocs är ett bra ställe att börja gräva vidare i alla replikeringsrelaterade funktioner i Postgres. Du bör titta på ämnen som fördröjd replikering, kaskadreplikering, synkrona väntelägen och mer.

Även om Postgres kommer med en imponerande uppsättning funktioner, finns det fortfarande användningsfall som inte stöds. Denna Postgres wikisida har en lista över tredjepartsverktyg som tillhandahåller ytterligare replikeringsrelaterad funktionalitet.


  1. SQL Inner join på utvalda satser

  2. Ta bort med Join in Oracle sql Query

  3. Utforska SQL Server Restore Database med återställning vs inga återställningsalternativ

  4. Räknar antalet förekomster av en delsträng i en sträng i PostgreSQL