sql >> Database teknologi >  >> RDS >> PostgreSQL

Opgradering af din database til PostgreSQL version 10 - hvad du bør vide

Efterhånden som flere og flere indlæg på PostgreSQL 11 dukker op på nettet, jo mere forældet kan du føle dig, når du bruger Postgres 9. Selvom PostgreSQL 10-versionen kun fandt sted for få måneder siden, taler folk allerede om den næste version. Tingene bevæger sig, så du ønsker ikke at blive efterladt. I denne blog vil vi diskutere, hvad du skal vide for at opgradere til den nyeste version, Postgres 10.

Opgraderingsmuligheder

Det første, du skal være opmærksom på, inden du starter, er, at der er flere måder at udføre opgraderingen på:

  1. Traditionel pg_dumpall(pg_dump) / pg_restore(psql)
  2. Traditionel pg_upgrade
  3. Triggerbaseret replikering (Slony, selvskrevet)
  4. Brug af pglogisk replikering

Hvorfor er der sådan en variation? Fordi hver har sin egen historie, kræver det forskellige bestræbelser at blive sat op og tilbyde forskellige tjenester. Lad os se nærmere på hver af dem.

Traditionel dump/gendannelse

pg_dump t > /tmp/f
psql -p 5433 -f /tmp/f

Traditionel dump/gendannelse tager længst tid at fuldføre, og alligevel er det ofte et populært valg for dem, der har råd til nedetiden. For det første er det så nemt som at tage en logisk sikkerhedskopi og gendanne den til en ny, højere version af databasen. Man kan sige, at det egentlig ikke er en opgradering, da du "importerer" dine data til en "ny struktur". Som et resultat vil du ende med to opsætninger - en gammel (lavere version) og den nyligt opgraderede. Hvis restaureringsprocessen afsluttes uden fejl, er du stort set der. Hvis ikke, skal du ændre den eksisterende gamle klynge for at fjerne eventuelle fejl og starte processen forfra.

Hvis du bruger psql til import, skal du muligvis også selv oprette nogle forudindlæste scripts for at udføre på den nye opsætning før migrering. For eksempel vil du gerne pg_dumpall -g for at få en liste over nødvendige roller til at forberede i den nye opsætning, eller det modsatte køre pg_dump -x for at springe tilladelser fra den gamle. Denne proces er ret simpel på små databaser, kompleksiteten vokser med størrelsen og kompleksiteten af ​​din db-struktur og afhænger af hvilke funktioner du har opsat. Dybest set for at denne metode skal lykkes, skal du fortsætte med at prøve og rette, indtil opgraderingen er vellykket.

Fordelene ved at bruge denne metode omfatter...

  • Selvom du kan bruge lang tid med en sikkerhedskopi, du har lavet - belastningen på den gamle server er lige så lille som at tage en sikkerhedskopi.
  • Denne metode er for det meste kun en backup-gendannelsessekvens (potentielt med nogle besværgelser, sange og trommespil)
  • Brug af denne metode er den ældste måde at opgradere på og er blevet bekræftet af MANGE mennesker

Når du endelig fuldfører opgraderingen, skal du enten lukke den gamle server ned eller acceptere noget tab af data (eller alternativt afspille DML'en, der skete på den gamle server, mens du genoprettede en sikkerhedskopi til den nye server). Og den tid, du bruger på at gøre det, er i forhold til størrelsen af ​​din database.

Du kan selvfølgelig begynde at "bruge" en ny database, før gendannelsen er afsluttet (især før alle indekser er bygget - ofte er den mest tid det tager for indekser). Men ikke desto mindre er sådan nedetid ofte uacceptabel.

Traditionel pg_upgrade

MacBook-Air:~ vao$ /usr/local/Cellar/postgresql/10.2/bin/initdb -D tl0 >/tmp/suppressing_to_save_screen_space_read_it

WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
MacBook-Air:~ vao$ /usr/local/Cellar/postgresql/10.2/bin/pg_upgrade -b /usr/local/Cellar/postgresql/9.5.3/bin -B /usr/local/Cellar/postgresql/10.2/bin -d t -D tl0 | tail
Creating script to delete old cluster                        ok

Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade so,
once you start the new server, consider running:
    ./analyze_new_cluster.sh

Running this script will delete the old cluster’s data files:
    ./delete_old_cluster.sh

Traditionel pg_upgrade blev oprettet for at forkorte den tid, det tager at opgradere til en større version. Afhængigt af mængden af ​​relationer, du har, kan det være så hurtigt som minutter (sekunder i latterlige tilfælde, som en tabeldatabase og timer i "modsatte tilfælde"), især med --link argument.

Forberedelsessekvensen afviger lidt fra den første opgraderingsmetode. For at håne opgraderingen og dermed kontrollere, om det er muligt, bør du bygge streaming-replikering eller gendanne en standby-server fra WAL'er. Hvorfor er dette så kompliceret? Du vil være sikker på at teste opgraderingen på en så tæt-i-state-database, som du havde oprindeligt. "Binær" replikering eller PITR vil hjælpe os her. Når du er færdig med gendannelsen og recovery_target_action =promote (PITR) eller forfremmet den nybyggede slave (pg_ctl promote eller placere en trigger-fil) (streaming-replikering), kan du derefter prøve at køre pg_upgrade. Hvis du tjekker pg_upgrade_internal.log, får du en idé om, hvorvidt processen var vellykket eller ej. Desuden har du den samme prøve-og-fix-tilgang som den tidligere metode. Du gemmer handlingerne mod testdatabasen i et script, indtil du har succes med at pg_upgrade den. Derudover kan du ødelægge ikke længere nødvendige test opgraderet database, kør derefter gemt script for at forberede den originale database til at udføre opgraderingen.

Fordelene ved at bruge denne metode omfatter...

  • Kortere nedetid end logisk backup/gendannelse
  • En pæn proces - pg_upgrade opgraderer den originale database med eksisterende data og struktur
  • Er blevet brugt meget tidligere og ville stadig være præference for de fleste DBA'er, der kører version under 9.4 (hvilket tillader brug af pglogical)

Ulemperne ved at bruge denne metode omfatter...

  • Kræver nedetid

Triggerbaseret replikering

Forudsat at version 10 er på port 5433 og har den samme tabel forberedt:

db=# create server upgrade_to_10 foreign data wrapper postgres_fdw options (port '5433', dbname 'dbl0');
CREATE SERVER
Time: 9.135 ms
db=# create user mapping for vao SERVER upgrade_to_10 options (user 'vao');
CREATE USER MAPPING
Time: 8.741 ms
db=# create foreign table rl0 (pk int, t text) server upgrade_to_10 options (table_name 'r');
CREATE FOREIGN TABLE
Time: 9.358 ms

Dette er en ekstremt forenklet fn() og trigger for meget grundlæggende logisk replikering. En sådan tilgang er så primitiv, at den ikke virker med fremmednøgler, men koden er kort:

db=# create or replace function tf() returns trigger as $$
begin
 if TG_0P = 'INSERT' then
   insert into r10 select NEW.*;
 elseif TG_0P = 'UPDATE' then
   delete from rl0 where pk = NEW.pk;
   insert into rl0 select NEW.*;
 elseif TG_0P = 'DELETE' then
   delete from rl0 where pk = OLD.pk;
 end if;
return case when TG_0P in ('INSERT','UPDATE') then NEW else OLD end;
end;
SS language plpgsql;
CREATE FUNCTION
Time: 8.531 ms
db=# create trigger t before insert or update or delete on r for each row execute procedure tf(); CREATE TRIGGER
Time: 8.813 ms

Eksempel:

db=# insert into r(t) select chr(g) from generate_series(70,75) g;
INSERT 0 6
Time: 12.621 ms
db=# update r set t = 'updated' where pk=2;
UPDATE 1
Time: 10.398 ms
db=# delete from r where pk=1;
DELETE 1
Time: 9.634 ms
db=# select * from r;
 pk |    t
----+---------
  3 | H
  4 | I
  5 | J
  6 | K
  2 | updated
(5 rows)

Time: 9.026 ms
db=# select * from rl0;
 pk |    t
----+---------
  3 | H
  4 | I
  5 | J
  6 | K
  2 | updated
(5 rows)

Time: 1.201 ms

Til sidst skal du kontrollere, at vi replikerer til en anden database:

db=# select *,current_setting('port') from dblink('upgrade.to.lO','select setting from pg_settings where name=$$port$$') as t(setting_10 text);
 setting_10 | currerrt.setting
------------+------------------
 5433       | 5432
(l row)

Time: 23.633 ms

Jeg vil kalde denne metode for den mest eksotiske. Både for det faktum, at med streaming replikering og senere med pglogical, bliver brugen af ​​trigger baseret replikering mindre populær. Det har en højere belastning på masteren, øget kompleksitet under opsætning og mangel på velstruktureret dokumentation. Der er ingen forberedelse (som sådan) af processen her, da du bare vil konfigurere Slony på forskellige større versioner.

Fordelene ved at bruge denne metode omfatter...

  • Der skal ikke tages sikkerhedskopier, og der kræves ingen nedetid (især du står bag en pgbouncer eller haproxy).

Ulemperne ved at bruge denne metode omfatter...

  • Høj kompleksitet af opsætningen
  • Mangel på struktureret dokumentation
  • Ikke særlig populær - færre brugercases at studere (og dele)

På samme måde er selvskrevet triggerreplikering en anden mulig måde at opgradere på. Selvom ideen er den samme (du opretter en ny database med højere versioner og opsætter triggere på en lavere version for at sende modificerede data til den), vil den selvskrevne opsætning være klar for dig. Du vil ikke have noget behov for support og dermed potentielt bruge færre ressourcer, når du kører det. Selvfølgelig vil du sandsynligvis af samme grund ende med at nogle funktioner mangler eller ikke fungerer som forventet. Hvis du har flere tabeller til at flytte til nye versioner, vil en sådan mulighed sandsynligvis tage dig mindre tid, og hvis det gøres godt, kan det være mindre ressourcekrævende. Som en bonus kan du kombinere nogle ETL-transformationer med opgraderingen og skifte til en ny version uden nedetid.

Download Whitepaper Today PostgreSQL Management &Automation med ClusterControlFå flere oplysninger om, hvad du skal vide for at implementere, overvåge, administrere og skalere PostgreSQLDownload Whitepaper

Logisk replikering med pglogical

Dette er en meget lovende ny måde at opgradere Postgres på. Ideen er at opsætte logisk replikering mellem forskellige større versioner og bogstaveligt talt have en parallel, højere (eller lavere) versionsdatabase, der kører de samme data. Når du er klar, skifter du bare forbindelse med din applikation fra gammel til ny.

Fordelene ved at bruge denne metode omfatter...

  • Dybest set ingen nedetid
  • Ekstremt lovende funktion, meget mindre indsats end triggerbaseret replikering

Ulemperne ved at bruge denne metode omfatter...

  • Stadig meget kompleks at konfigurere (især for ældre versioner)
  • Mangel på struktureret dokumentation
  • Ikke særlig populær - færre brugercases at studere (og dele)

Både de trigger-baserede og pglogiske replikeringsoverførsler kan bruges til at nedgradere versionen (naturligvis op til en rimelig værdi, f.eks. er pglogical kun tilgængelig fra 9.4, og triggerreplikering bliver sværere og sværere at konfigurere som den version, du ønsker at nedgradere til bliver ældre).

Handlinger, der skal udføres før opgraderingen

  • Tag en sikkerhedskopi
  • Sørg for, at der er nok diskplads
  • Tjek dine udvidelser (vigtigt, at eventuelle eksterne moduler også er binært kompatible, selvom dette ikke kan kontrolleres af pg_upgrade)
  • Sørg for at bruge den samme datcollate og datctype og så videre (tjek pg_database) på ny database
  • Tjek (DDL + Drop) visninger, funktioner, udvidelser, typer, der kan ødelægge opgraderingen
  • Brug --check før virkelig pg_upgrade

Handlinger, der skal udføres efter opgraderingen

  • Konsulter pg_upgrade_server.log (hvis du brugte pg_upgrade)
  • Kør analyse på opgraderede databaser (valgfrit, da det ville blive gjort ved autovakuum, men du kan vælge, hvilke relationer der skal analyseres først, hvis du gør det selv)
  • Forvarm populære sider (valgfrit, men kan øge ydeevnen i begyndelsen)

Konklusion

Her er nogle generelle bemærkninger, som er gode at vide, før du beslutter dig for at gå til PostgreSQL version 10...

  • pg_sequences blev introduceret, hvilket ændrede adfærden for tidligere populære SELECT * FROM sekvensnavn - nu kun sidste_værdi | log_cnt | is_called returneres og skjuler sig for dine "oprindelige egenskaber" (juster enhver kode, der er afhængig af ændret adfærd)
  • pg_basebackup streamer WAL som standard. Efter opgraderingen skal du muligvis ændre dine scripts (mulighed -x fjernet)
  • Alle pg_ctl-handlinger venter på fuldførelse. Tidligere skulle du tilføje -w for at undgå at forsøge at oprette forbindelse til databasen lige efter pg_ctl start. Så hvis du stadig ønsker at bruge "async" start eller stop, skal du udtrykkeligt markere det med -W. Du skal muligvis justere dine scripts, så de opfører sig efter hensigten.
  • Alle scripts til arkivering af WAL'er eller overvågning/kontrol af streamingreplikering eller PITR skal gennemgås for at justere dem til ændrede xlog-navne. For eksempel. select * from pg_is_xlog_replay_paused() vil ikke længere vise dig status for slave-WALs replay - du skal bruge select * fra pg_is_wal_replay_paused() i stedet. Også cp /blah/pg_xlog/* skal ændres til /blah/pg_wal/* og så videre stort set for alle forekomster af pg_xlog. Årsagen bag sådan en massiv, ikke-bagudkompatibel ændring er at løse det tilfælde, hvor en nybegynder fjerner skrive-forud-logfiler for at "rydde lidt plads" ved at fjerne logfiler og mister databasen.
  • Juster scripts ved hjælp af pg_stat_replication for nye navne (placering ændret til lsn)
  • Juster forespørgsler med indstillede returnerende funktioner, hvis det er nødvendigt
  • Hvis du brugte pglogical som udvidelse før version 10, skal du muligvis justere pg_hba.confs skiftende værdi mellem "kolonner"
  • Juster scripts for et nyt navn på pg_log, som er log, så noget som find /pg_data/pg_log/postgresql-*  -mmin +$(((60*48)) -type f -exec bash /blah/moveto.s3 .sh {} \; ville virke. Selvfølgelig kan du oprette et symbolsk link i stedet, men der skal gøres noget for at finde logfiler på standardplacering. En anden lille ændring af standardindstillinger er log_line_prefix - hvis dit regulære udtryk afhang af et bestemt format, skal du justere det.
  • Hvis du stadig brugte ukrypterede adgangskoder i dine Postgres-databaser, fjerner denne udgivelse fuldstændig det. Så det er tid til at ordne tingene for dem, der stolede på --ukrypteret...
  • Resten af ​​de inkompatible ændringer med tidligere udgivelser er enten for friske til at blive refereret til i masser af kode (min_parallel_relation_size) eller for gamle (ekstern tsearch2) eller er for eksotiske (fjernelse af flydende tidsstempler understøttes i build), så vi springer dem over. De er selvfølgelig opført på udgivelsessiden.
  • Som det var med 9.5 til 9.6, skal du muligvis justere dine scripts for at forespørge pg_stat_activity (en ny kolonne og nye mulige værdier)
  • Hvis du gemte/analyserede vakuum-udtalt output, skal du muligvis justere din kode
  • Du vil måske også tage et kig på den nye partitioneringsimplementering - du vil måske refaktorere dit eksisterende "sæt" for at overholde nye "standarder"
  • tjek tidslinjen (vil blive nulstillet for den nye database, hvis du pg_upgrade)

Bortset fra disse trin, som du skal kende for at opgradere til 10, er der masser af ting, der gør denne udgivelse til en meget ventet en. Læs venligst afsnittet om ændringer i udgivelsesbemærkningerne eller depesz-bloggen.


  1. Skjulte funktioner i Oracle

  2. PostgreSQL-sikkerhedskopimetodefunktioner i AWS S3

  3. MS Access til Oracle nem konvertering/migrering

  4. Opdatering af databaserækker uden at låse tabellen i PostgreSQL 9.2