PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Aktualisieren Ihrer Datenbank auf PostgreSQL Version 10 – Was Sie wissen sollten

Je mehr Beiträge zu PostgreSQL 11 im Web erscheinen, desto veralteter fühlen Sie sich bei der Verwendung von Postgres 9. Obwohl die Veröffentlichung der PostgreSQL 10-Version erst vor wenigen Monaten erfolgte, sprechen die Leute bereits über die nächste Version. Die Dinge bewegen sich, also möchten Sie nicht zurückgelassen werden. In diesem Blog besprechen wir, was Sie wissen müssen, um auf die neueste Version, Postgres 10, zu aktualisieren.

Upgrade-Optionen

Das erste, was Sie wissen sollten, bevor Sie beginnen, ist, dass es mehrere Möglichkeiten gibt, das Upgrade durchzuführen:

  1. Traditionelles pg_dumpall(pg_dump) / pg_restore(psql)
  2. Traditionelles pg_upgrade
  3. Trigger-basierte Replikation (Slony, selbstgeschrieben)
  4. Verwendung pglogischer Replikation

Warum gibt es eine solche Vielfalt? Weil jede eine andere Geschichte hat, unterschiedliche Anstrengungen erfordert, um eingerichtet zu werden, und unterschiedliche Dienstleistungen anbietet. Sehen wir uns jeden von ihnen genauer an.

Traditionelles Dump/Restore

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

Das traditionelle Dump/Restore dauert am längsten und ist dennoch oft eine beliebte Wahl für diejenigen, die sich die Ausfallzeit leisten können. Erstens ist es so einfach wie ein logisches Backup zu erstellen und es in einer neuen, höheren Version der Datenbank wiederherzustellen. Man könnte wirklich sagen, dass es sich nicht um ein Upgrade handelt, da Sie Ihre Daten in eine „neue Struktur“ „importieren“. Als Ergebnis erhalten Sie zwei Setups - ein altes (niedrigere Version) und das neu aktualisierte. Wenn der Wiederherstellungsprozess fehlerfrei abgeschlossen wird, haben Sie es fast geschafft. Wenn nicht, müssen Sie den vorhandenen alten Cluster ändern, um Fehler zu beseitigen, und den Vorgang erneut starten.

Wenn Sie psql für den Import verwenden, müssen Sie möglicherweise auch einige Preload-Skripts selbst erstellen, um sie vor der Migration auf dem neuen Setup auszuführen. Beispielsweise möchten Sie pg_dumpall -g ausführen, um eine Liste der erforderlichen Rollen für die Vorbereitung im neuen Setup zu erhalten, oder im Gegenteil pg_dump -x ausführen, um die Berechtigungen des alten zu überspringen. Dieser Prozess ist bei kleinen Datenbanken ziemlich einfach, die Komplexität wächst mit der Größe und Komplexität Ihrer Datenbankstruktur und hängt davon ab, welche Funktionen Sie eingerichtet haben. Damit diese Methode erfolgreich ist, müssen Sie im Grunde so lange versuchen und beheben, bis das Upgrade erfolgreich ist.

Zu den Vorteilen dieser Methode gehören...

  • Während Sie mit einer Sicherung, die Sie erstellt haben, möglicherweise viel Zeit verbringen, ist die Last auf dem alten Server so gering wie die Erstellung einer Sicherung.
  • Diese Methode ist meistens nur eine Sicherungs-Wiederherstellungs-Sequenz (möglicherweise mit einigen Zaubersprüchen, Liedern und Trommeln)
  • Die Verwendung dieser Methode ist die älteste Art des Upgrades und wurde von VIELEN Personen verifiziert

Wenn Sie das Upgrade endgültig abgeschlossen haben, müssen Sie entweder den alten Server herunterfahren oder einen Datenverlust akzeptieren (oder alternativ die DML wiederholen, die auf dem alten Server aufgetreten ist, während Sie eine Sicherung auf dem neuen Server wiederherstellen). Und die dafür aufgewendete Zeit ist relativ zur Größe Ihrer Datenbank.

Sie können natürlich damit beginnen, eine neue Datenbank zu "benutzen", bevor die Wiederherstellung abgeschlossen ist (insbesondere bevor alle Indizes erstellt sind - oft dauert es am längsten für Indizes). Trotzdem sind solche Ausfallzeiten oft nicht akzeptabel.

Traditionelles 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

Das traditionelle pg_upgrade wurde erstellt, um die Zeit zu verkürzen, die für das Upgrade auf eine Hauptversion benötigt wird. Abhängig von der Anzahl der Beziehungen, die Sie haben, kann es Minuten dauern (Sekunden in lächerlichen Fällen, wie einer Tabellendatenbank und Stunden in den "entgegengesetzten Fällen"), insbesondere mit dem --link-Argument.

Die Vorbereitungssequenz weicht geringfügig von der ersten Upgrade-Methode ab. Um das Upgrade zu simulieren und somit zu prüfen, ob es möglich ist, sollten Sie eine Streaming-Replikation erstellen oder einen Standby-Server von WALs wiederherstellen. Warum ist das so kompliziert? Sie möchten sicher sein, dass Sie das Upgrade auf einer Datenbank mit möglichst geringem Status testen, wie Sie es ursprünglich hatten. Hier hilft uns die "binäre" Replikation oder PITR. Nachdem Sie die Wiederherstellung abgeschlossen und recovery_target_action =promote (PITR) oder den neu gebauten Slave hochgestuft haben (pg_ctl promote oder eine Triggerdatei platzieren) (Streaming-Replikation) können Sie dann versuchen, pg_upgrade auszuführen. Die Überprüfung von pg_upgrade_internal.log gibt Ihnen eine Vorstellung davon, ob der Vorgang erfolgreich war oder nicht. Darüber hinaus haben Sie den gleichen Try-and-Fix-Ansatz wie bei der vorherigen Methode. Sie speichern die an der Testdatenbank vorgenommenen Aktionen in einem Skript, bis Sie sie erfolgreich pg_upgrade. Außerdem können Sie nicht mehr benötigte Prüfungen vernichten aktualisierte Datenbank, führen Sie das gespeicherte Skript aus, um die ursprüngliche Datenbank für die Durchführung des Upgrades vorzubereiten.

Zu den Vorteilen dieser Methode gehören…

  • Kürzere Ausfallzeit als logische Sicherung/Wiederherstellung
  • Ein sauberer Prozess - pg_upgrade aktualisiert die ursprüngliche Datenbank mit vorhandenen Daten und Strukturen
  • Wurde in der Vergangenheit häufig verwendet und wäre immer noch die Präferenz für die meisten DBAs, die eine Version unter 9.4 ausführen (was die Verwendung von pglogical erlaubt)

Zu den Nachteilen dieser Methode gehören…

  • Erfordert Ausfallzeiten

Triggerbasierte Replikation

Angenommen, Version 10 befindet sich auf Port 5433 und hat dieselbe Tabelle vorbereitet:

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

Dies ist ein extrem vereinfachtes fn() und ein Auslöser für eine sehr einfache logische Replikation. Ein solcher Ansatz ist so primitiv, dass er mit Fremdschlüsseln nicht funktioniert, aber der Code ist kurz:

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

Beispiel:

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

Überprüfen Sie zuletzt, ob wir in eine andere Datenbank replizieren:

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

Ich würde diese Methode als die exotischste bezeichnen. Sowohl für die Tatsache, dass mit der Streaming-Replikation als auch später mit pglogical die Verwendung der Trigger-basierten Replikation weniger populär wird. Es hat eine höhere Belastung des Masters, eine erhöhte Komplexität beim Einrichten und einen Mangel an gut strukturierter Dokumentation. Es gibt hier keine Vorbereitung (als solche) des Prozesses, da Sie Slony nur auf verschiedenen Hauptversionen einrichten möchten.

Zu den Vorteilen dieser Methode gehören…

  • Es müssen keine Backups erstellt werden und es sind keine Ausfallzeiten erforderlich (insbesondere Sie befinden sich hinter einem Pgbouncer oder Haproxy).

Zu den Nachteilen dieser Methode gehören…

  • Hohe Komplexität der Einrichtung
  • Mangel an strukturierter Dokumentation
  • Nicht sehr beliebt – weniger Anwendungsfälle zum Studieren (und Teilen)

In gleicher Weise ist die selbst geschriebene Trigger-Replikation eine weitere mögliche Upgrade-Möglichkeit. Während die Idee dieselbe ist (Sie starten eine neue Datenbank einer höheren Version und richten Trigger in einer niedrigeren Version ein, um geänderte Daten dorthin zu senden), wird Ihnen die selbst geschriebene Einrichtung klar sein. Sie benötigen keinen Support und verbrauchen daher möglicherweise weniger Ressourcen, wenn Sie es ausführen. Natürlich werden Sie aus dem gleichen Grund wahrscheinlich am Ende damit enden, dass einige Funktionen fehlen oder nicht wie erwartet funktionieren. Wenn Sie mehrere Tabellen auf neue Versionen verschieben müssen, wird eine solche Option wahrscheinlich weniger Zeit in Anspruch nehmen und, wenn sie gut gemacht ist, weniger Ressourcen verbrauchen. Als Bonus können Sie einige ETL-Transformationen mit dem Upgrade kombinieren und ohne Ausfallzeit auf eine neue Version umsteigen.

Laden Sie noch heute das Whitepaper PostgreSQL-Verwaltung und -Automatisierung mit ClusterControl herunterErfahren Sie, was Sie wissen müssen, um PostgreSQL bereitzustellen, zu überwachen, zu verwalten und zu skalierenLaden Sie das Whitepaper herunter

Logische Replikation mit pglogical

Dies ist eine sehr vielversprechende neue Art, Postgres zu aktualisieren. Die Idee besteht darin, eine logische Replikation zwischen verschiedenen Hauptversionen einzurichten und buchstäblich eine parallele Datenbank mit höheren (oder niedrigeren) Versionen zu haben, auf der dieselben Daten ausgeführt werden. Wenn Sie bereit sind, wechseln Sie einfach die Verbindungen mit Ihrer Anwendung von alt zu neu.

Zu den Vorteilen dieser Methode gehören…

  • Grundsätzlich keine Ausfallzeiten
  • Äußerst vielversprechendes Feature, viel weniger Aufwand als Trigger-basierte Replikation

Zu den Nachteilen dieser Methode gehören…

  • Immer noch sehr komplex einzurichten (insbesondere für ältere Versionen)
  • Mangel an strukturierter Dokumentation
  • Nicht sehr beliebt – weniger Anwendungsfälle zum Studieren (und Teilen)

Sowohl die Trigger-basierte als auch die pglogical-Replikation der Hauptversionsmigrationen können verwendet werden, um die Version herunterzustufen (natürlich bis zu einem vernünftigen Wert, z. B. ist pglogical erst ab 9.4 verfügbar und die Trigger-Replikation wird immer schwieriger als die gewünschte Version einzurichten um herunterzustufen, um älter zu werden).

Vor dem Upgrade zu ergreifende Maßnahmen

  • Erstellen Sie eine Sicherungskopie
  • Stellen Sie sicher, dass genügend Speicherplatz vorhanden ist
  • Überprüfen Sie Ihre Erweiterungen (wichtig, dass alle externen Module auch binärkompatibel sind, obwohl dies nicht von pg_upgrade überprüft werden kann)
  • Vergewissern Sie sich, dass Sie in der neuen Datenbank dasselbe Datum und denselben Datentyp usw. verwenden (überprüfen Sie pg_database)
  • Überprüfen Sie (DDL + Drop) Ansichten, Funktionen, Erweiterungen, Typen, die das Upgrade unterbrechen könnten
  • Verwenden Sie --check bevor Sie wirklich pg_upgrade

Aktionen nach dem Upgrade

  • Konsultieren Sie pg_upgrade_server.log (falls Sie pg_upgrade verwendet haben)
  • Lassen Sie die Analyse auf aktualisierten Datenbanken laufen (optional, wie es durch Autovacuum geschehen würde, aber Sie können wählen, welche Beziehungen zuerst analysiert werden sollen, wenn Sie es selbst tun)
  • Beliebte Seiten vorwärmen (optional, könnte aber am Anfang die Leistung steigern)

Schlussfolgerung

Hier sind einige allgemeine Hinweise, die Sie wissen sollten, bevor Sie sich entscheiden, zu PostgreSQL Version 10 zu wechseln…

  • pg_sequences wurden eingeführt und änderten das Verhalten des zuvor beliebten SELECT * FROM sequence_name - jetzt nur noch last_value | log_cnt | is_called werden zurückgegeben, wobei die "Anfangseigenschaften" vor Ihnen verborgen werden (jeden Code anpassen, der auf geändertem Verhalten beruht)
  • pg_basebackup streamt standardmäßig WAL. Nach dem Upgrade müssen Sie möglicherweise Ihre Skripte ändern (Option -x entfernt)
  • Alle pg_ctl-Aktionen warten auf ihren Abschluss. Bisher mussten Sie -w hinzufügen, um zu vermeiden, dass Sie versuchen, direkt nach dem Start von pg_ctl eine Verbindung zur Datenbank herzustellen. Wenn Sie also weiterhin "async" starten oder stoppen möchten, müssen Sie dies explizit mit -W markieren. Möglicherweise müssen Sie Ihre Skripte anpassen, damit sie sich wie beabsichtigt verhalten.
  • Alle Skripte zum Archivieren von WALs oder zum Überwachen/Steuern von Streaming-Replikation oder PITR müssen überprüft werden, um sie an geänderte xlog-Namen anzupassen. Z.B. select * from pg_is_xlog_replay_paused() zeigt Ihnen nicht länger den Status der Slave-WALs-Wiedergabe - Sie müssen stattdessen select * from pg_is_wal_replay_paused() verwenden. Auch cp /blah/pg_xlog/* muss grundsätzlich für alle Vorkommen von pg_xlog in /blah/pg_wal/* geändert werden und so weiter. Der Grund hinter solch einer massiven, nicht abwärtskompatiblen Änderung besteht darin, den Fall anzugehen, wenn ein Neuling Write-Ahead-Logs entfernt, um durch das Entfernen von Logs "etwas Platz zu schaffen", und die Datenbank verliert.
  • Passen Sie Skripte mit pg_stat_replication für neue Namen an (Speicherort in lsn geändert)
  • Passen Sie bei Bedarf Abfragen mit festgelegten Rückgabefunktionen an
  • Wenn Sie pglogical als Erweiterung vor Version 10 verwendet haben, müssen Sie möglicherweise den Wert von pg_hba.conf zwischen "Spalten" anpassen
  • Passen Sie Skripte für einen neuen Namen von pg_log an, der log ist, also so etwas wie find /pg_data/pg_log/postgresql-*  -mmin +$((60*48)) -type f -exec bash /blah/moveto.s3 .Sch {} \; würde funktionieren. Natürlich können Sie stattdessen einen symbolischen Link erstellen, aber es müssten Maßnahmen ergriffen werden, um Protokolle am Standardspeicherort zu finden. Eine weitere kleine Änderung an den Standardeinstellungen ist log_line_prefix - wenn Ihr regulärer Ausdruck von einem bestimmten Format abhing, müssen Sie es anpassen.
  • Wenn Sie noch unverschlüsselte Passwörter in Ihren Postgres-Datenbanken verwendet haben, entfernt diese Version diese vollständig. Es ist also an der Zeit, die Dinge für diejenigen zu klären, die sich auf --unencrypted...
  • verlassen haben
  • Der Rest der inkompatiblen Änderungen mit früheren Releases sind entweder zu frisch, um in viel Code referenziert zu werden (min_parallel_relation_size) oder zu alt (extern tsearch2) oder zu exotisch (Entfernung der Unterstützung für Fließkomma-Zeitstempel im Build). wir werden sie überspringen. Natürlich sind sie auf der Release-Seite aufgelistet.
  • Wie bei 9.5 bis 9.6 müssen Sie möglicherweise Ihre Skripte für die Abfrage von pg_stat_activity anpassen (eine neue Spalte und neue mögliche Werte)
  • Wenn Sie die ausführliche Vakuumausgabe gespeichert/analysiert haben, müssen Sie möglicherweise Ihren Code anpassen
  • Vielleicht möchten Sie auch einen Blick auf die neue Partitionierungsimplementierung werfen - vielleicht möchten Sie Ihren bestehenden "Satz" umgestalten, um den neuen "Standards" zu entsprechen
  • Überprüfen Sie die Zeitleiste (wird für die neue Datenbank zurückgesetzt, wenn Sie pg_upgrade ausführen)

Abgesehen von diesen Schritten, die Sie kennen müssen, um auf 10 zu aktualisieren, gibt es viele Dinge, die diese Version zu einer mit Spannung erwarteten machen. Bitte lesen Sie den Abschnitt über Änderungen in den Versionshinweisen oder im depesz-Blog.