sql >> Databasteknik >  >> RDS >> PostgreSQL

Uppgradering till PostgreSQL 11 med logisk replikering

Det är dags.

För ungefär ett år sedan publicerade vi PostgreSQL 10 med stöd för inbyggd logisk replikering. En av användningsområdena för logisk replikering är att tillåta uppgradering med låg eller ingen stilleståndstid mellan PostgreSQL-huvudversioner. Hittills var PostgreSQL 10 den enda PostgreSQL-versionen med inbyggd logisk replikering, så det fanns inte många möjligheter att uppgradera på detta sätt. (Logisk replikering kan också användas för att flytta data mellan instanser på olika operativsystem eller CPU-arkitekturer eller med olika lågnivåkonfigurationsinställningar som blockstorlek eller lokalisering — sidgradering om du så vill.) Nu när PostgreSQL 11 är nära kommer det att finnas fler skäl att använda den här funktionen.

Låt oss först jämföra de tre huvudsakliga sätten att uppgradera en PostgreSQL-installation:

  • pg_dump och återställ
  • pg_upgrade
  • logisk replikering

Vi kan jämföra dessa metoder när det gäller robusthet, hastighet, nödvändig stilleståndstid och begränsningar (med mera, men vi måste sluta någonstans för den här artikeln).

pg_dump and restore är utan tvekan den mest robusta metoden, eftersom den är den mest testade och har använts i årtionden. Den har också väldigt få begränsningar vad gäller vad den kan hantera. Det är möjligt att konstruera databaser som inte kan dumpas och återställas, de flesta involverar speciella objektberoenderelationer, men de är sällsynta och involverar vanligtvis avskräckta metoder.

Problemet med dump- och återställningsmetoden är förstås att den effektivt kräver driftstopp under hela tiden som dumpnings- och återställningsoperationerna pågår. Medan källdatabasen fortfarande är läsbar och skrivbar medan processen körs, kommer alla uppdateringar av källdatabasen efter starten av dumpningen att gå förlorade.

pg_upgrade förbättrar pg_dump-processen genom att flytta över datafilerna direkt utan att behöva dumpa dem i en logisk textform. Observera att pg_upgrade fortfarande använder pg_dump internt för att kopiera schemat, men inte data. När pg_upgrade var ny ifrågasattes dess robusthet, och den uppgraderade vissa databaser felaktigt. Men pg_upgrade är nu ganska mogen och väl testad, så man behöver inte tveka på att använda den av den anledningen längre. Medan pg_upgrade körs är databassystemet nere. Men man kan göra ett val om hur länge pg_upgrade körs. I standardkopieringsläget är den totala körtiden sammansatt av tiden för att dumpa och återställa schemat (vilket vanligtvis är mycket snabbt, om man inte har tusentals tabeller eller andra objekt) plus tiden för att kopiera datafilerna, vilket beror på hur stor databasen är (och I/O-systemet, filsystemet, etc.).

I det valfria länkläget är datafilerna istället hårdlänkade till den nya datakatalogen, så att tiden bara är tiden för att utföra en kort kärnoperation per fil istället för att kopiera varje byte. Nackdelen är att om något går fel med uppgraderingen eller om du behöver gå tillbaka till den gamla installationen, kommer denna operation att ha förstört din gamla databas. (Jag arbetar på en lösning av båda världarna för PostgreSQL 12 med hjälp av återlänkar eller filklonoperationer på filsystem som stöds.)

Logisk replikering är den nyaste av gänget här, så det kommer förmodligen att ta lite tid att reda ut knäcken. Om du inte har tid att utforska och undersöka kanske det inte är rätt väg att gå just nu. (Naturligtvis har människor använt andra logiska replikeringslösningar som inte är kärnor som Slony, Londiste och pglogical för att uppgradera PostgreSQL i många år, så det finns mycket erfarenhet av principerna, om inte med detaljerna.)

Fördelen med att använda logisk replikering för att uppgradera är att applikationen kan fortsätta att köras mot den gamla instansen medan datasynkroniseringen sker. Det behöver bara vara ett litet avbrott medan klientanslutningarna växlas över. Så även om en uppgradering med logisk replikering förmodligen är långsammare från början till slut än att använda pg_upgrade i kopieringsläge (och definitivt långsammare än att använda hårdlänksläge), spelar det inte så stor roll eftersom den faktiska stilleståndstiden kan vara mycket kortare.

Observera att logisk replikering för närvarande inte replikerar schemaändringar. I denna föreslagna uppgraderingsprocedur kopieras schemat fortfarande via pg_dump, men efterföljande schemaändringar överförs inte. Uppgradering med logisk replikering har också några andra begränsningar. Vissa operationer fångas inte upp av logisk replikering:stora objekt, TRUNCATE, sekvensändringar. Vi kommer att diskutera lösningar på dessa problem senare.

Om du har några fysiska beredskapslägen (och om inte, varför gör du inte det?), Det finns också några skillnader att tänka på mellan metoderna. Med båda metoderna måste du bygga nya fysiska väntelägen för den uppgraderade instansen. Med dump och återställning såväl som med logisk replikering kan de sättas på plats innan uppgraderingen startar så att standby-läget för det mesta är klart när återställningen eller den logiska replikeringens initiala synkronisering är klar, med förbehåll för replikeringsfördröjning.

Med pg_upgrade måste de nya standbylägena skapas efter att uppgraderingen av den primära är klar. (Pg_upgrade-dokumentationen beskriver detta mer detaljerat.) Om du förlitar dig på fysiska beredskapslägen för hög tillgänglighet, bör beredskapslägena vara på plats innan du byter till den nya instansen, så inställningen av beredskapslägena kan påverka dina övergripande tidsberäkningar.

Men tillbaka till logisk replikering. Så här kan uppgradering med logisk replikering göras:

0. Den gamla instansen måste förberedas för logisk replikering. Detta kräver vissa konfigurationsinställningar som beskrivs under http://www.postgresql.org/docs/10/static/logical-replication-config.html (främst wal_level = logical . Om det visar sig att du behöver göra dessa ändringar kommer de att kräva en omstart av servern. Så kontrollera detta i god tid. Kontrollera också att pg_hba.conf på den gamla instansen är inställd för att acceptera anslutningar från den nya instansen. (Att ändra som kräver bara en omladdning.)

1. Installera den nya PostgreSQL-versionen. Du behöver åtminstone serverpaketet och klientpaketet som innehåller pg_dump. Många förpackningar tillåter nu installation av flera versioner sida vid sida. Om du kör virtuella maskiner eller molninstanser är det värt att överväga att installera den nya instansen på en ny värd.

2. Skapa en ny instans, det vill säga kör initdb. Den nya instansen kan ha andra inställningar än den gamla, till exempel locale, WAL-segmentstorlek eller checksumming. (Varför inte använda den här möjligheten för att aktivera datakontrollsummor?)

3. Innan du startar den nya instansen kan du behöva ändra några konfigurationsinställningar. Om instansen körs på samma värd som den gamla instansen måste du ställa in ett annat portnummer. Överför också alla anpassade ändringar du har gjort i postgresql.conf på din gamla instans, som minnesinställningar, max_connections , etc. Gör på samma sätt pg_hba.conf inställningar som passar din miljö. Du kan vanligtvis börja med att kopiera över pg_hba.conf fil från den gamla instansen. Om du vill använda SSL, ställ in det nu.

4. Starta den nya (tomma) instansen och kontrollera att den fungerar tillfredsställande. Om du ställer in den nya instansen på en ny värd, kontrollera nu att du kan göra en databasanslutning (med psql) från den nya värddatorn till den gamla databasinstansen. Vi kommer att behöva det i de efterföljande stegen.

5. Kopiera över schemadefinitionerna med pg_dumpall. (Eller så kan du göra det med pg_dump för varje databas separat, men glöm sedan inte globala objekt som roller.)

pg_dumpall -s >schemadump.sql
psql -d postgres -f schemadump.sql

Eventuella schemaändringar efter denna punkt kommer inte att migreras. Du skulle behöva hantera dem själv. I många fall kan du bara använda den ändrade DDL på båda värdarna, men att köra kommandon som ändrar tabellstrukturen under en uppgradering är förmodligen en utmaning för långt.

6. Skapa en publikation som fångar alla tabeller i varje databas i källinstansen:

CREATE PUBLICATION p_upgrade FOR ALL TABLES;

Logisk replikering fungerar separat i varje databas, så detta måste upprepas i varje databas. Å andra sidan behöver du inte uppgradera alla databaser på en gång, så du kan göra den här en databas åt gången eller till och med inte uppgradera vissa databaser.

7. Skapa en prenumeration i varje databas i målinstansen som prenumererar på den nyss skapade publikationen. Se till att matcha käll- och måldatabaserna korrekt.

CREATE SUBSCRIPTION s_upgrade CONNECTION 'host=oldhost port=oldport dbname=dbname ...' PUBLICATION p_upgrade;

Ställ in anslutningsparametrarna efter behov.

8. Nu väntar du tills prenumerationerna har kopierats över de initiala uppgifterna och har kommit ikapp förlaget fullt ut. Du kan kontrollera den initiala synkroniseringsstatusen för varje tabell i en prenumeration i systemkatalogen pg_subscription_rel (leta efter r =redo i kolumnen srsubstate ). Den övergripande statusen för replikeringen kan kontrolleras i pg_stat_replication på sändningssidan och pg_stat_subscription på den mottagande sidan.

9. Som nämnts ovan, replikeras inte sekvensändringar. En möjlig lösning för detta är att kopiera över sekvensvärdena med pg_dump. Du kan få en dump av de aktuella sekvensvärdena med något sånt här:

pg_dump -d dbname --data-only -t '*_seq' >seq-data.sql

(Detta förutsätter att sekvensnamnen alla matchar *_seq och inga tabeller matchar det namnet. I mer komplicerade fall kan du också gå vägen att skapa en fullständig dump och extrahera sekvensdata från dumpens innehållsförteckning.)

Eftersom sekvenserna kan avancera medan du gör detta, kanske du använder seq-data.sql fil för att lägga till lite slack till siffrorna.

Återställ sedan filen till den nya databasen med psql.

10. Showtime:Byt applikationer till de nya instanserna. Detta kräver en del eftertanke i förväg. I det enklaste scenariot stoppar du dina applikationsprogram, ändrar anslutningsinställningarna, startar om. Om du använder en anslutningsproxy kan du växla över anslutningen där. Du kan också byta klientapplikationer en efter en, kanske för att testa saker lite eller lätta på belastningen på det nya systemet. Detta kommer att fungera så länge som de applikationer som fortfarande pekar på den gamla servern och de som pekar på den nya servern inte skriver motstridiga. (I så fall skulle du köra ett multimastersystem, åtminstone under en kort tid, och det är en annan ordning av komplexitet.)

11. När uppgraderingen är klar kan du riva replikeringsinställningarna. Kör

i varje databas på den nya instansen
DROP SUBSCRIPTION s_upgrade;

Om du redan har stängt av den gamla instansen kommer detta att misslyckas eftersom den inte kommer att kunna nå fjärrservern för att släppa replikeringsplatsen. Se DROP SUBSCRIPTION man-sidan för hur du går tillväga i den här situationen.

Du kan också släppa publikationerna på källinstansen, men det är inte nödvändigt eftersom en publikation inte behåller några resurser.

12. Ta slutligen bort de gamla instanserna om du inte behöver dem längre.

Några ytterligare kommentarer om lösningar för saker som logisk replikering inte stöder. Om du använder stora objekt kan du flytta över dem med pg_dump, naturligtvis så länge de inte ändras under uppgraderingsprocessen. Detta är en betydande begränsning, så om du är en stor användare av stora objekt, kanske den här metoden inte är något för dig. Om din applikation utfärdar TRUNCATE under uppgraderingsprocessen, kommer dessa åtgärder inte att replikeras. Kanske kan du justera din applikation för att förhindra att den gör det under tiden för uppgraderingen, eller så kan du ersätta en DELETE istället. PostgreSQL 11 kommer att stödja replikering av TRUNCATE, men det fungerar bara om både källan och destinationsinstansen är PostgreSQL 11 eller nyare.

Några avslutande kommentarer som verkligen gäller alla uppgraderingsåtaganden:

  • Applikationer och alla databasklientprogram bör testas mot en ny större PostgreSQL-version innan de sätts i produktion.
  • I detta syfte bör du också testa uppgraderingsproceduren innan du kör den i produktionsmiljön.
  • Skriv ner saker eller bättre skript och automatisera så mycket som möjligt.
  • Se till att dina säkerhetskopieringsinställningar, övervakningssystem och eventuella underhållsverktyg och skript justeras på lämpligt sätt under uppgraderingsproceduren. Helst bör dessa vara på plats och verifieras innan övergången görs.

Med det i åtanke, lycka till och dela gärna med dig av dina erfarenheter.


  1. postgresql - sql - antal "sanna" värden

  2. Hur man ändrar storleken på en kolumn i SQL Server (T-SQL)

  3. 7 alternativ för att aktivera rör (||) som sammanfogningsoperatör i MariaDB

  4. Hur lägger man till en ny kolumn i MYSQL-tabellen?