sql >> Database >  >> RDS >> PostgreSQL

Uw database upgraden naar PostgreSQL versie 10 - wat u moet weten

Naarmate er meer en meer berichten over PostgreSQL 11 op het web verschijnen, kunt u zich verouderd voelen bij het gebruik van Postgres 9. Hoewel de versie van PostgreSQL 10 pas enkele maanden geleden is uitgebracht, hebben mensen het al over de volgende versie. Dingen zijn in beweging, dus je wilt niet achterblijven. In deze blog bespreken we wat u moet weten om te upgraden naar de nieuwste versie, Postgres 10.

Upgrade-opties

Het eerste waar u zich van bewust moet zijn voordat u begint, is dat er verschillende manieren zijn om de upgrade uit te voeren:

  1. Traditionele pg_dumpall(pg_dump) / pg_restore(psql)
  2. Traditionele pg_upgrade
  3. Triggergebaseerde replicatie (Slony, zelfgeschreven)
  4. Pglogische replicatie gebruiken

Waarom is er zo'n verscheidenheid? Omdat elk een andere geschiedenis heeft, verschillende inspanningen vereist om op te zetten en verschillende diensten aan te bieden. Laten we ze allemaal nader bekijken.

Traditionele dumpen/herstellen

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

Traditioneel dumpen/herstel duurt het langst en toch is het vaak een populaire keuze voor diegenen die zich de downtime kunnen veroorloven. Ten eerste is het net zo eenvoudig als een logische back-up maken en deze terugzetten naar een nieuwe, hogere versie van de database. Je zou kunnen zeggen dat het eigenlijk geen upgrade is, omdat je je gegevens "importeert" naar een "nieuwe structuur". Als resultaat krijg je twee setups - een oude (lagere versie) en de nieuw geüpgradede. Als het herstelproces zonder fouten wordt voltooid, bent u er zo ongeveer. Als dat niet het geval is, moet u het bestaande oude cluster wijzigen om eventuele fouten te elimineren en het proces opnieuw te starten.

Als u psql gebruikt voor het importeren, moet u mogelijk ook zelf enkele preload-scripts maken om uit te voeren op de nieuwe installatie voorafgaand aan de migratie. U zou bijvoorbeeld pg_dumpall -g willen gebruiken om een ​​lijst met benodigde rollen te krijgen om voor te bereiden in de nieuwe setup, of het tegenovergestelde uitvoeren van pg_dump -x om machtigingen van de oude over te slaan. Dit proces is vrij eenvoudig voor kleine databases, de complexiteit groeit met de grootte en complexiteit van uw db-structuur en hangt af van de functies die u hebt ingesteld. Om deze methode succesvol te laten zijn, moet je blijven proberen en repareren totdat de upgrade is gelukt.

De voordelen van het gebruik van deze methode zijn onder meer...

  • Hoewel je misschien een lange tijd bezig bent met één back-up die je hebt gemaakt, is de belasting van de oude server net zo klein als het maken van één back-up.
  • Deze methode is meestal slechts een back-up-herstelsequentie (mogelijk met enkele spreuken, liedjes en drummen)
  • Het gebruik van deze methode is de oudste manier om te upgraden en is geverifieerd door VEEL mensen

Wanneer u de upgrade definitief voltooit, moet u ofwel de oude server afsluiten of enig gegevensverlies accepteren (of als alternatief de DML afspelen die op de oude server is gebeurd terwijl u een back-up naar de nieuwe server terugzet). En de tijd die hieraan wordt besteed, is relatief aan de grootte van uw database.

U kunt natuurlijk beginnen met het "gebruiken" van een nieuwe database voordat het herstel is voltooid (vooral voordat alle indexen zijn gebouwd - vaak is de meeste tijd die nodig is voor indexen). Maar toch is een dergelijke uitvaltijd vaak onaanvaardbaar.

Traditionele 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

Traditionele pg_upgrade is gemaakt om de tijd die nodig is om te upgraden naar een hoofdversie te verkorten. Afhankelijk van het aantal relaties dat je hebt, kan het zo snel zijn als minuten (seconden in belachelijke gevallen, zoals een tabeldatabase en uren in de "tegenovergestelde gevallen"), vooral met --link argument.

De voorbereidingsvolgorde verschilt enigszins van de eerste upgrademethode. Om de upgrade te spotten en dus te controleren of het mogelijk is, moet u streaming-replicatie bouwen of een standby-server herstellen van WAL's. Waarom is dit zo ingewikkeld? U wilt er zeker van zijn dat u de upgrade test op een as-close-in-state-database zoals u oorspronkelijk had. "Binaire" replicatie of PITR zal ons hierbij helpen. Nadat u het herstel hebt voltooid en herstel_target_action =promoot (PITR) of de nieuw gebouwde slaaf hebt gepromoot (pg_ctl promoot of plaatst een triggerbestand) (streamingreplicatie), kunt u proberen pg_upgrade uit te voeren. Als u de pg_upgrade_internal.log controleert, krijgt u een idee of het proces succesvol was of niet. Verder heb je dezelfde try-and-fix-aanpak als de vorige methode. U slaat de acties die zijn ondernomen tegen de testdatabase op in een script, totdat u deze met succes pg_upgrade. Bovendien kunt u niet langer benodigde test . vernietigen geüpgradede database, voer dan het opgeslagen script uit om de originele database voor te bereiden voor het uitvoeren van de upgrade.

De voordelen van het gebruik van deze methode zijn onder meer...

  • Kortere uitvaltijd dan logische back-up/herstel
  • Een mooi proces - pg_upgrade upgradet de originele database met bestaande gegevens en structuur
  • Is in het verleden veel gebruikt en zou nog steeds de voorkeur hebben voor de meeste DBA's met een versie onder 9.4 (waardoor pglogical kan worden gebruikt)

De nadelen van het gebruik van deze methode zijn onder meer...

  • Vereist uitvaltijd

Triggergebaseerde replicatie

Ervan uitgaande dat versie 10 op poort 5433 staat en dezelfde tabel heeft voorbereid:

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

Dit is een extreem simplistische fn() en trigger voor zeer eenvoudige logische replicatie. Een dergelijke benadering is zo primitief dat het niet werkt met externe sleutels, maar de code is 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

Voorbeeld:

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

Ten slotte controleren of we repliceren naar een andere 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

Ik zou deze methode de meest exotische noemen. Zowel vanwege het feit dat met streaming-replicatie en later met pglogical het gebruik van op triggers gebaseerde replicatie minder populair wordt. Het heeft een hogere belasting van de master, verhoogde complexiteit tijdens de installatie en een gebrek aan goed gestructureerde documentatie. Er is hier geen voorbereiding (als zodanig) van het proces, omdat je Slony gewoon op verschillende hoofdversies wilt instellen.

De voordelen van het gebruik van deze methode zijn onder meer...

  • Er hoeven geen back-ups te worden gemaakt en er is geen downtime nodig (vooral als u achter een pgbouncer of haproxy zit).

De nadelen van het gebruik van deze methode zijn onder meer...

  • Hoge complexiteit van installatie
  • Gebrek aan gestructureerde documentatie
  • Niet erg populair - minder gebruikerscases om te bestuderen (en te delen)

In dezelfde lijn is zelfgeschreven triggerreplicatie een andere mogelijke manier om te upgraden. Hoewel het idee hetzelfde is (u start een nieuwe database met een hogere versie op en stelt triggers in op een lagere versie om gewijzigde gegevens ernaar te verzenden), de zelfgeschreven configuratie zal u duidelijk zijn. U heeft geen ondersteuning nodig en gebruikt dus mogelijk minder bronnen bij het uitvoeren ervan. Natuurlijk zul je om dezelfde reden waarschijnlijk eindigen met een aantal functies die ontbreken of niet werken zoals verwacht. Als je meerdere tabellen hebt om naar nieuwe versies te gaan, kost zo'n optie je waarschijnlijk minder tijd en, als je het goed doet, kan het minder bronnen verbruiken. Als bonus kunt u enkele ETL-transformaties combineren met de upgrade, zodat u zonder downtime overschakelt naar een nieuwe versie.

Download de whitepaper vandaag PostgreSQL-beheer en -automatisering met ClusterControlLees wat u moet weten om PostgreSQL te implementeren, bewaken, beheren en schalenDownload de whitepaper

Logische replicatie met pglogical

Dit is een veelbelovende nieuwe manier om Postgres te upgraden. Het idee is om logische replicatie tussen verschillende hoofdversies op te zetten en letterlijk een parallelle, hogere (of lagere) versiedatabase te hebben met dezelfde gegevens. Als je klaar bent, schakel je gewoon de verbindingen met je applicatie van oud naar nieuw.

De voordelen van het gebruik van deze methode zijn onder meer...

  • In principe geen uitvaltijd
  • Zeer veelbelovende functie, veel minder inspanning dan op triggers gebaseerde replicatie

De nadelen van het gebruik van deze methode zijn onder meer...

  • Nog steeds zeer complex om in te stellen (vooral voor oudere versies)
  • Gebrek aan gestructureerde documentatie
  • Niet erg populair - minder gebruikerscases om te bestuderen (en te delen)

Zowel de op triggers gebaseerde als pglogische replicatie grote versiemigraties kunnen worden gebruikt om de versie te downgraden (tot een redelijke waarde natuurlijk, bijv. pglogical is alleen beschikbaar vanaf 9.4 en triggerreplicatie wordt steeds moeilijker in te stellen als de versie die u wilt om te downgraden om ouder te worden).

Te ondernemen acties vóór de upgrade

  • Maak een back-up
  • Zorg dat er voldoende schijfruimte is
  • Controleer uw extensies (belangrijk dat eventuele externe modules ook binair compatibel zijn, hoewel dit niet kan worden gecontroleerd door pg_upgrade)
  • Zorg ervoor dat u hetzelfde datcollate en datctype enzovoort gebruikt (controleer pg_database) in de nieuwe database
  • Controleer (DDL + Drop) weergaven, functies, extensies, typen die de upgrade zouden kunnen verbreken
  • Gebruik --check voor echt pg_upgrade

Acties die moeten worden genomen na de upgrade

  • Raadpleeg pg_upgrade_server.log (als je pg_upgrade hebt gebruikt)
  • Voer analyse uit op geüpgradede databases (optioneel, zoals het zou worden gedaan door autovacuüm, maar u kunt kiezen welke relaties eerst moeten worden geanalyseerd als u het zelf doet)
  • Verwarm populaire pagina's voor (optioneel, maar kan in het begin de prestaties verbeteren)

Conclusie

Hier zijn enkele algemene opmerkingen die goed zijn om te weten voordat u besluit naar PostgreSQL versie 10 te gaan…

  • pg_sequences werden geïntroduceerd, waardoor het gedrag van voorheen populaire SELECT * FROM sequence_name - nu alleen last_value | log_cnt | is_calls worden geretourneerd en verbergen voor u "initiële eigenschappen" (pas elke code aan die afhankelijk is van gewijzigd gedrag)
  • pg_basebackup streamt standaard WAL. Na de upgrade moet u mogelijk uw scripts wijzigen (optie -x verwijderd)
  • Alle pg_ctl-acties wachten op voltooiing. Voorheen moest u -w toevoegen om te voorkomen dat u direct na het starten van pg_ctl verbinding probeert te maken met de database. Dus als u nog steeds "async" start of stop wilt gebruiken, moet u dit expliciet markeren met -W. Mogelijk moet u uw scripts aanpassen zodat ze zich gedragen zoals bedoeld.
  • Alle scripts voor het archiveren van WAL's of het bewaken/controleren van streamingreplicatie of PITR moeten worden herzien om ze aan te passen aan gewijzigde xlog-namen. bijv. select * from pg_is_xlog_replay_paused() zal je niet langer de status van slave WAL's replay tonen - je moet in plaats daarvan select * from pg_is_wal_replay_paused() gebruiken. Ook moet cp /blah/pg_xlog/* worden gewijzigd in /blah/pg_wal/* enzovoort, in principe voor alle voorkomens van pg_xlog. De reden achter zo'n enorme, niet achterwaarts compatibele verandering is om het geval aan te pakken waarin een newby vooruitschrijflogs verwijdert om "wat ruimte vrij te maken" door logs te verwijderen, en de database verliest.
  • Scripts aanpassen met pg_stat_replication voor nieuwe namen (locatie gewijzigd in lsn)
  • Pas zo nodig zoekopdrachten aan met ingestelde terugkerende functies
  • Als je pglogical als extensie gebruikte vóór versie 10, moet je mogelijk de waarde van pg_hba.conf aanpassen tussen "kolommen"
  • Pas scripts aan voor een nieuwe naam van pg_log die log is, dus zoiets als find /pg_data/pg_log/postgresql-*  -mmin +$((60*48)) -type f -exec bash /blah/moveto.s3 .sh {} \; zou werken. Natuurlijk kunt u in plaats daarvan een symbolische link maken, maar er moet actie worden ondernomen om logboeken op de standaardlocatie te vinden. Een andere kleine wijziging in de standaardinstellingen is log_line_prefix - als uw reguliere expressie afhankelijk was van een bepaalde indeling, moet u deze aanpassen.
  • Als u nog steeds niet-versleutelde wachtwoorden in uw Postgres-databases gebruikte, verwijdert deze volledige versie dit. Dus het is tijd om dingen uit te zoeken voor degenen die vertrouwden op --unencrypted...
  • De rest van de incompatibele wijzigingen met eerdere releases zijn ofwel te nieuw om in veel code naar te verwijzen (min_parallel_relation_size) of te oud (externe tsearch2) of zijn te exotisch (verwijdering van drijvende-komma tijdstempels ondersteuning in build), dus we zullen ze overslaan. Natuurlijk staan ​​ze vermeld op de releasepagina.
  • Zoals het was met 9.5 tot 9.6, moet u mogelijk uw scripts aanpassen voor het opvragen van pg_stat_activity (een nieuwe kolom en nieuwe mogelijke waarden)
  • Als u uitgebreide vacuümuitvoer aan het opslaan/analyseren was, moet u mogelijk uw code aanpassen
  • Misschien wil je ook eens kijken naar de nieuwe implementatie van partitionering - je zou je bestaande "set" kunnen refactoren om te voldoen aan nieuwe "standaarden"
  • controleer de tijdlijn (wordt gereset voor de nieuwe database als u pg_upgrade)

Afgezien van deze stappen die u moet kennen om te upgraden naar 10, zijn er tal van dingen die deze release tot een langverwachte release maken. Lees het gedeelte over wijzigingen in de release-opmerkingen of depesz-blog.


  1. Bewaking van query's op SQL Server

  2. Een opgeslagen procedure maken in SQL Server

  3. 12c VARCHAR2(32767)

  4. MySQL:transactie binnen een opgeslagen procedure