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

Logische Replikationspartitionierung mit PostgreSQL 13

Jedes PostgreSQL-Release kommt mit einigen wichtigen Feature-Verbesserungen, aber was ebenso interessant ist, ist, dass jedes Release auch Verbesserungen gegenüber früheren Features aufweist.

Da PostgreSQL 13 bald veröffentlicht werden soll, ist es an der Zeit, zu prüfen, welche Funktionen und Verbesserungen uns die Community bringt. Eine solche Verbesserung ohne Rauschen ist die „Verbesserung der logischen Replikation für die Partitionierung.“

Lassen Sie uns diese Funktionsverbesserung anhand eines laufenden Beispiels verstehen.

Terminologie

Zwei Begriffe, die zum Verständnis dieser Funktion wichtig sind, sind:

  • Partitionstabellen
  • Logische Replikation

Partitionstabellen

Eine Möglichkeit, eine große Tabelle in mehrere physische Teile aufzuteilen, um folgende Vorteile zu erzielen:

  • Verbesserte Abfrageleistung
  • Schnellere Updates
  • Schnelleres Massenladen und -löschen
  • Selten verwendete Daten auf langsamen Laufwerken organisieren

Einige dieser Vorteile werden durch Partitionsbereinigung (d. h. Abfrageplaner, der die Partitionsdefinition verwendet, um zu entscheiden, ob eine Partition gescannt werden soll oder nicht) und die Tatsache erreicht, dass eine Partition eher einfacher in endlichen Speicher passt im Vergleich zu einem riesigen Tisch.

Eine Tabelle wird partitioniert nach:

  • Liste
  • Hash
  • Bereich

Logische Replikation 

Wie der Name schon sagt, handelt es sich hierbei um eine Replikationsmethode, bei der Daten basierend auf ihrer Identität (z. B. Schlüssel) inkrementell repliziert werden. Es ist nicht vergleichbar mit WAL oder physikalischen Replikationsmethoden, bei denen Daten Byte für Byte gesendet werden.

Basierend auf einem Publisher-Subscriber-Muster muss die Quelle der Daten einen Publisher definieren, während das Ziel als Abonnent registriert sein muss. Die interessanten Anwendungsfälle dafür sind:

  • Selektive Replikation (nur ein Teil der Datenbank)
  • Gleichzeitiges Schreiben in zwei Datenbankinstanzen, in denen Daten repliziert werden
  • Replikation zwischen verschiedenen Betriebssystemen (z. B. Linux und Windows)
  • Feinkörnige Sicherheit bei der Replikation von Daten 
  • Löst die Ausführung aus, wenn Daten auf der Empfängerseite eintreffen 

Logische Replikation für Partitionen

Mit den Vorteilen sowohl der logischen Replikation als auch der Partitionierung ist es ein praktischer Anwendungsfall, ein Szenario zu haben, in dem eine partitionierte Tabelle über zwei PostgreSQL-Instanzen repliziert werden muss.

Im Folgenden finden Sie die Schritte, um die in PostgreSQL 13 vorgenommenen Verbesserungen in diesem Zusammenhang zu etablieren und hervorzuheben.

Einrichtung

Erwägen Sie eine Einrichtung mit zwei Knoten, um zwei verschiedene Instanzen auszuführen, die eine partitionierte Tabelle enthalten:

Die Schritte für Instanz_1 sind wie folgt:Nach der Anmeldung unter 192.168.56.101 als Postgres-Benutzer :

$ initdb -D ${HOME}/pgdata-1

$ echo "listen_addresses = '192.168.56.101'"  >> ${HOME}/pgdata-1/postgresql.conf

$ echo "wal_level = logical"                  >> ${HOME}/pgdata-1/postgresql.conf

$ echo "host postgres all 192.168.56.102/32 md5" >> ${HOME}/pgdata-1/pg_hba.conf

$ pg_ctl -D ${HOME}/pgdata-1 -l logfile start

Die Einstellung „wal_level“ ist speziell auf „logical“ gesetzt, um anzugeben, dass die logische Replikation verwendet wird, um Daten von dieser Instanz zu replizieren. Die Konfigurationsdatei „pg_hba.conf“ wurde ebenfalls geändert, um Verbindungen von 192.168.56.102 zuzulassen.

# CREATE TABLE stock_sales

( sale_date date not null, unit_sold  int, unit_price int )

  PARTITION BY RANGE ( sale_date );

# CREATE TABLE stock_sales_y2017 PARTITION OF stock_sales

  FOR VALUES FROM ('2017-01-01') TO ('2018-01-01'); 

# CREATE TABLE stock_sales_y2018 PARTITION OF stock_sales

  FOR VALUES FROM ('2018-01-01') TO ('2019-01-01');

# CREATE TABLE stock_sales_default

  PARTITION OF stock_sales DEFAULT;

Obwohl die Postgres-Rolle standardmäßig auf der Datenbank Instance_1 erstellt wird, sollte auch ein separater Benutzer erstellt werden, der eingeschränkten Zugriff hat – was den Bereich nur für eine bestimmte Tabelle einschränkt.

# CREATE ROLE rep_usr WITH REPLICATION LOGIN PASSWORD 'rep_pwd';

# GRANT CONNECT ON DATABASE postgres TO rep_usr;

# GRANT USAGE ON SCHEMA public TO rep_usr;

# GRANT SELECT ON ALL TABLES IN SCHEMA public to rep_usr;

Eine fast ähnliche Einrichtung ist für Instanz_2 erforderlich

$ initdb -D ${HOME}/pgdata-2

$ echo "listen_addresses = '192.168.56.102'"  >> ${HOME}/pgdata-2/postgresql.conf

$ pg_ctl -D ${HOME}/pgdata-2 -l logfile start

Es sollte beachtet werden, dass, da Instance_2 keine Datenquelle für andere Knoten sein wird, die wal_level-Einstellungen sowie die Datei pg_hba.conf keine zusätzlichen Einstellungen benötigen. Unnötig zu erwähnen, dass pg_hba.conf je nach Produktionsanforderungen möglicherweise aktualisiert werden muss.

Logische Replikation unterstützt DDL nicht, wir müssen auch eine Tabellenstruktur auf Instanz_2 erstellen. Erstellen Sie eine partitionierte Tabelle mithilfe der obigen Partitionserstellung, um dieselbe Tabellenstruktur auch auf Instance_2 zu erstellen.

Einrichtung der logischen Replikation

Die Einrichtung der logischen Replikation wird mit PostgreSQL 13 viel einfacher. Bis PostgreSQL 12 war die Struktur wie folgt:

Mit PostgreSQL 13 wird die Veröffentlichung von Partitionen viel einfacher. Sehen Sie sich das folgende Diagramm an und vergleichen Sie es mit dem vorherigen Diagramm:

Bei Setups mit Hunderten und Tausenden von partitionierten Tabellen vereinfacht diese kleine Änderung Dinge zu einem großen Teil.

In PostgreSQL 13 lauten die Anweisungen zum Erstellen einer solchen Veröffentlichung:

CREATE PUBLICATION rep_part_pub FOR TABLE stock_sales 

WITH (publish_via_partition_root);

Der Konfigurationsparameter publish_via_partition_root ist neu in PostgreSQL 13, wodurch der Empfängerknoten eine etwas andere Blatthierarchie haben kann. Die bloße Erstellung von Veröffentlichungen auf partitionierten Tabellen in PostgreSQL 12 gibt Fehlermeldungen wie die folgenden zurück:

ERROR:  "stock_sales" is a partitioned table

DETAIL:  Adding partitioned tables to publications is not supported.

HINT:  You can add the table partitions individually.

Ignorieren wir die Einschränkungen von PostgreSQL 12 und fahren wir mit unserem praktischen Einsatz dieser Funktion auf PostgreSQL 13 fort, müssen wir den Abonnenten auf Instanz_2 mit den folgenden Anweisungen einrichten:

CREATE SUBSCRIPTION rep_part_sub CONNECTION 'host=192.168.56.101 port=5432 user=rep_usr password=rep_pwd dbname=postgres' PUBLICATION rep_part_pub;

Überprüfen, ob es wirklich funktioniert

Wir sind mit der gesamten Einrichtung ziemlich fertig, aber lassen Sie uns ein paar Tests durchführen, um zu sehen, ob alles funktioniert.

Fügen Sie auf Instanz_1 mehrere Zeilen ein und stellen Sie sicher, dass sie in mehreren Partitionen erscheinen:

# INSERT INTO stock_sales (sale_date, unit_sold, unit_price) VALUES ('2017-09-20', 12, 151);# INSERT INTO stock_sales (sale_date, unit_sold, unit_price) VALUES ('2018-07-01', 22, 176);

# INSERT INTO stock_sales (sale_date, unit_sold, unit_price) VALUES ('2016-02-02', 10, 1721);

Prüfen Sie die Daten auf Instanz_2:

# SELECT * from stock_sales; 

sale_date  | unit_sold | unit_price

------------+-----------+------------

 2017-09-20 |    12 |    151

 2018-07-01 |    22 |    176

 2016-02-02 |    10 |   1721

Lassen Sie uns nun prüfen, ob die logische Replikation funktioniert, auch wenn die Blattknoten auf der Empfängerseite nicht gleich sind.

Fügen Sie eine weitere Partition auf Instanz_1 hinzu und fügen Sie den Datensatz ein:

# CREATE TABLE stock_sales_y2019

      PARTITION OF stock_sales 

     FOR VALUES FROM ('2019-01-01') to ('2020-01-01');

# INSERT INTO stock_sales VALUES(‘2019-06-01’, 73, 174 );

Prüfen Sie die Daten auf Instanz_2:

# SELECT * from stock_sales;

 sale_date  | unit_sold | unit_price

------------+-----------+------------

 2017-09-20 |    12 |    151

 2018-07-01 |    22 |    176

 2016-02-02 |    10 |   1721

 2019-06-01 |    73 |   174

Andere Partitionierungsfunktionen in PostgreSQL 13

Es gibt auch andere Verbesserungen in PostgreSQL 13, die sich auf die Partitionierung beziehen, nämlich:

  1. Verbesserungen beim Join zwischen partitionierten Tabellen
  2. Partitionierte Tabellen unterstützen jetzt BEFORE-Trigger auf Zeilenebene

Fazit

Ich werde die oben genannten zwei bevorstehenden Funktionen auf jeden Fall in meinen nächsten Blogs überprüfen. Bis dahin Stoff zum Nachdenken – segelt PostgreSQL mit der kombinierten Kraft der Partitionierung und logischen Replikation einem Master-Master-Setup näher?