Nach erfolgreichem Dritten Beta im August 2024 hat die PostgreSQL-Entwicklergruppe die GA-Version am 26. September veröffentlicht. recently Ich habe in meinem Blog über einige der wichtigsten logischen Replikationsfunktionen geschrieben, die Sie in PostgreSQL 17 erkennen werden. In diesem Blog post
werde ich zwei neue Leistungsfeatures beschreiben, die Sie in Postgres 17 finden sowie eine weitere wichtige logische Replikationsfunktion, die ich in meinem vorherigen Blog des gleichen Seriens nicht behandelt habe.
PostgreSQL hat im Verlaufe der Jahre außergewöhnlich viel gewachsen und mit jeder bedeutenden Veröffentlichung ist es zu einer robuster, zuverlässigeren und reaktiveren Datenbank für sowohl mission-critical als auch nicht mission-critical enterprise applications geworden. Die global und lebhafte PostgreSQL-Community ist für den Erfolg von PostgreSQL verantwortlich, indem sie sicherstellt, dass alle Änderungen sorgfältig geprüft und reviewed werden, bevor sie zum Projektsourcode hinzugefügt werden. Es ist auch sehr ermutigend, zu sehen, dass große Technologienamen wie Microsoft, Google, Apple und andere in Postgres investieren, indem sie in-house Expertise entwickeln und der Open-Source-Community zurueckgeben.
Verbesserungen an der logischen Replikation pfadieren den Weg für die addierte verteilte PostgreSQL-Unterstützung zur Kernfunktionalität. verteiltes PostgreSQL bezeichnet die Implementierung von PostgreSQL in einer verteilten Architektur, die die verbesserte Skalierbarkeit, die Fault Tolerance und die verbesserte Leistung auf mehreren Knoten ermöglicht.
Nun, ohne weitere Verzögerung, lass uns über einige Leistungsfeatures von PostgreSQL 17 diskutieren. Verbesserte Abfrageleistung Mit Materialisierten CTEs
Common Table Expressions (CTEs) in PostgreSQL sind vorübergehende Ergebnismengen, die innerhalb eines SELECT
, INSERT
, UPDATE
oder DELETE
-Ausdrucks referenziert werden können. Sie verbessern die Lesbarkeit und die Organisation komplexer Abfragen und können rekursiv sein, was sie besonders nützlich für hierarchische Daten macht. Der grundlegende Syntax einer CTE-Abfrage lautet wie folgt:
WITH cte_names AS
(– QUERY here )
Select * from cte_names;
Verwende das Schlüsselwort WITH
in einer Abfrage, um die CTE zu definieren; der übergeordnete Abfrage (die das Ergebnis集 definiert) folgt nach dem AS
-Klausel dem CTE-Namen. Nach der Definition der CTE kann Sie den CTE durch seinen Namen referenzieren, um das Ergebnis集 der CTE zu verwenden und weitere Operationen auf dem Ergebnis集 innerhalb derselben Abfrage durchzuführen.
PostgreSQL 17 verbessert weiterhin die Leistung und Fähigkeiten rund um CTEs, einschließlich Verbesserungen in der Abfrageplanung und -ausführung. Ältere Versionen von Postgres behandeln CTEs als Optimierungssperren, was bedeutet, dass der Planer die Prädikate nicht in sie hinein schieben konnte. Allerdings kann man ab PostgreSQL 12 effizientere Ausführungspläne definieren. Stelle immer Ihre Abfragen unter die Lupe und beachte die Ausführungspläne, wenn Leistung kritisch ist.
Leistungshinweis: Wenn du mehrmals auf das gleiche Ergebnissatz verweist, erzeuge den CTE mit dem Schlüsselwort MATERIALIZED
. Wenn du einen materialisierten CTE erstellst, berechnet und speichert Postgres das Ergebnis des übergeordneten Abfrages. Dadurch müssen anschließende Abfragen nicht mehrmals komplizierte Berechnungen durchführen, wenn du auf den CTE mehrmals verweist.
Extrahierung von Spaltenstatistiken aus CTE-Referenzen, Postgres 17 verbessert materialisierte CTEs
Ein materialisierter CTE fungiert grundsätzlich als Optimierungszaun, was bedeutet, dass der äußere Abfrage der Plan der untergeordneten Abfrage nicht beeinflussen wird, sobald der Plan festgelegt wurde. Der äußere Abfrage ist auf die vermutete Breite und die Zeilenanzahl des CTE-Ergebnissatzes zugänglich, weshalb es sinnvoll ist, die Spaltenstatistiken von der untergeordneten Abfrage auf den Planer für den äußeren Abfrage zu übertragen. Der äußere Abfrage kann die verfügbaren Informationen nutzen, was die Übertragung der Spaltenstatistikinformationen von der untergeordneten Abfrage bis zum Plan der äußeren Abfrage ermöglicht, aber nicht in den CTE-Plan hinab.
Dieser Fehler wurde der Community mit einem einfachen Testfall gemeldet, der die Verbesserung und den Einfluss auf den Abfrageplaner aufgrund dieser Verbesserung demonstrieren kann.
Beispiel: Vergleich von Postgres 16-Verhalten mit Postgres 17
Zuerst erzeugen wir unser Arbeitsumfeld in Postgres 16 und führen gegen dieses ANALYZE
durch: zwei Tabellen und Indizes:
postgres=# create table t1(a int);
CREATE TABLE
postgres=# create table t2(b int);
CREATE TABLE
postgres=# create index my_index on t1 using btree (a);
CREATE INDEX
postgres=# insert into t1 select generate_series(1, 100000) from generate_series(1, 3);
INSERT 0 300000
postgres=# insert into t2 select generate_series(1, 100) from generate_series(1, 10);
INSERT 0 1000
postgres=# analyze t1;
ANALYZE
postgres=# analyze t2;
ANALYZE
Then, we create our materialized CTE:
postgres=# explain analyze with my_cte as materialized (select b from t2) select *
from t1 where t1.a in (select b from my_cte);
The query plan from our Postgres 16 code sample contains:
QUERY PLAN
----------------------------------------------------------------------
Nested Loop (cost=37.92..856.50 rows=2966 width=4) (actual time=0.574..0.722 rows=300 loops=1)
CTE my_cte
-> Seq Scan on t2 (cost=0.00..15.00 rows=1000 width=4) (actual time=0.038..0.161 rows=1000 loops=1)
-> HashAggregate (cost=22.50..24.50 rows=200 width=4) (actual time=0.449..0.461 rows=100 loops=1)
Group Key: my_cte.b
Batches: 1 Memory Usage: 40kB
-> CTE Scan on my_cte (cost=0.00..20.00 rows=1000 width=4) (actual time=0.046..0.322 rows=1000 loops=1)
-> Index Only Scan using my_index on t1 (cost=0.42..4.06 rows=3 width=4) (actual time=0.002..0.002 rows=3 loops=1
00)
Index Cond: (a = my_cte.b)
Heap Fetches: 0
Planning Time: 1.242 ms
Execution Time: 1.051 ms
(12 rows)
Wie Sie in den Abfrageplan sehen können, sind die Spaltenstatistiken von 200 Zeilen der Unterabfrage falsch, was die Gesamtplanung beeinträchtigt.
-> HashAggregate (cost=22.50..24.50 rows=200 width=4) (actual time=0.449..0.461 rows=100 loops=1)
Group Key: my_cte.b
Dann testen wir die gleiche Setup- und Abfrage gegen PostgreSQL 17:
postgres=# explain analyze with my_cte as materialized (select b from t2) select *
from t1 where t1.a in (select b from my_cte);
QUERY PLAN
-------------------------------------------------------------------------------------------------
---------------------------------
Merge Join (cost=42.25..54.29 rows=302 width=4) (actual time=0.627..0.712 rows=300 loops=1)
Merge Cond: (t1.a = my_cte.b)
CTE my_cte
-> Seq Scan on t2 (cost=0.00..15.00 rows=1000 width=4) (actual time=0.031..0.134 rows=1000
loops=1)
-> Index Only Scan using my_index on t1 (cost=0.42..7800.42 rows=300000 width=4) (actual tim
e=0.027..0.049 rows=301 loops=1)
Heap Fetches: 0
-> Sort (cost=26.82..27.07 rows=100 width=4) (actual time=0.598..0.604 rows=100 loops=1)
Sort Key: my_cte.b
Sort Method: quicksort Memory: 25kB
-> HashAggregate (cost=22.50..23.50 rows=100 width=4) (actual time=0.484..0.494 rows=1
00 loops=1)
Group Key: my_cte.b
Batches: 1 Memory Usage: 24kB
-> CTE Scan on my_cte (cost=0.00..20.00 rows=1000 width=4) (actual time=0.033..0
.324 rows=1000 loops=1)
Planning Time: 1.066 ms
Execution Time: 0.946 ms
(15 rows)
Wie Sie in den Abfrageplan für Postgres 17 sehen können, werden die Spaltenstatistiken aus der Unterabfrage korrekt an den oberen Planer der äußeren Abfrage weitergeleitet. Dies hilft PostgreSQL, einen besseren Plan zu wählen, der die Ausführungszeit der Abfrage verbessert.
Dies ist eine einfache Abfrage, aber bei größeren und komplexeren Abfragen kann dieser Änderung eine erhebliche Leistungsdifferenz leadern.
Verteilung von Pfad Schlüsseln von einem CTE auf eine äußere Abfrage
Eine weitere interessante Verbesserung der CTE-Funktionalität in Postgres 17 ist die Weitergabe von Pfad Schlüsseln aus der Unterabfrage an die äußere Abfrage. In PostgreSQL sind Pfad Schlüssel ein Bestandteil des Abfrageplanerstellungsprozesses und werden hauptsächlich zur Sortierung und Reihenfolge von Zeilen in Abfragen verwendet, die geordnete Ergebnisse benötigen, wie z.B. Abfragen mit einem ORDER BY
-Ausschnitt oder wenn Sortierung für andere Operationen wie Merge Joins erforderlich ist.
Vor Postgres 17 wurde die Sortierreihenfolge der materialisierten CTE-Unterabfrage nicht mit der äußeren Abfrage geteilt, auch wenn die Sortierreihenfolge durch einen Index Scan-Knoten oder einen Sortier-Knoten gewährleistet war. Ohne gegarantierte Sortierreihenfolge lässt sich der PostgreSQL-Planer zu einem weniger optimierten Plan entscheiden, während eine gegarantierte Sortierreihenfolge dafür sorgt, dass es wahrscheinlicher ist, einen optimierten Plan zu wählen.
Mit PostgreSQL 17 kann der Planer Informationen einer verwirklichten CTE mit einer bestimmten Sortierreihenfolge wiederverwenden, um das Verhalten der äußeren Abfrage zu verbessern. Dies verbessert das Performance, indem redundante Sortierungen vermieden oder effizientere Join-Verfahren ermöglicht werden. Wie in den Commit-Kommentaren von Tom Lane dargelegt:
„Der Code zur Verhängung von Pathkeys in die äußere Abfrage existiert bereits für normale
RTE_SUBQUERY
-Subabfragen, aber wurde für CTEs nicht verwendet, möglicherweise aus Sorge, die Optimierungssperre zwischen CTE und äußerer Abfrage zu aufrechtzuerhalten.“
Diese einfache Änderung am PostgreSQL-Quellcode sollte zu Verbesserungen der Leistung führen, wenn es sich bei Abfragen um komplexe CTEs handelt, insbesondere dort, wo Sortierungen oder Merge-Joins aufgrund der impliziten Reihenfolge der CTE-Ergebnisse optimiert werden können.
Hier ist ein Beispiel mit den Daten in PostgreSQL regression:
postgres=# CREATE TABLE tenk1 (
postgres(# unique1 int4,
postgres(# unique2 int4,
postgres(# two int4,
postgres(# four int4,
postgres(# ten int4,
postgres(# twenty int4,
postgres(# hundred int4,
postgres(# thousand int4,
postgres(# twothousand int4,
postgres(# fivethous int4,
postgres(# tenthous int4,
postgres(# odd int4,
postgres(# even int4,
postgres(# stringu1 name,
postgres(# stringu2 name,
postgres(# string4 name
postgres(# );
CREATE TABLE
postgres=# CREATE INDEX tenk1_unique1 ON tenk1 USING btree(unique1 int4_ops);
CREATE INDEX
postgres=# \copy tenk1 FROM '~/projects/postgres/src/test/regress/data/tenk.data';
COPY 10000
postgres=# VACUUM ANALYZE tenk1;
VACUUM
Der Abfrageplan unseres Postgres 16-Codebeispiels enthält folgendes:
postgres=# explain analyze with x as materialized (select unique1 from tenk1 b order by unique1)
select count(*) from tenk1 a
where unique1 in (select * from x);
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------
---
Aggregate (cost=764.29..764.30 rows=1 width=8) (actual time=21.592..21.593 rows=1 loops=1)
CTE x
-> Index Only Scan using tenk1_unique1 on tenk1 b (cost=0.29..306.29 rows=10000 width=4) (actual time=0.046..1.415 rows=10000 loops=
1)
Heap Fetches: 0
-> Nested Loop (cost=225.28..445.50 rows=5000 width=0) (actual time=7.545..20.911 rows=10000 loops=1)
-> HashAggregate (cost=225.00..227.00 rows=200 width=4) (actual time=7.535..9.051 rows=10000 loops=1)
Group Key: x.unique1
Batches: 1 Memory Usage: 929kB
-> CTE Scan on x (cost=0.00..200.00 rows=10000 width=4) (actual time=0.070..3.933 rows=10000 loops=1)
-> Index Only Scan using tenk1_unique1 on tenk1 a (cost=0.29..1.08 rows=1 width=4) (actual time=0.001..0.001 rows=1 loops=10000)
Index Cond: (unique1 = x.unique1)
Heap Fetches: 0
Planning Time: 0.806 ms
Execution Time: 21.890 ms
(14 rows)
Der Abfrageplan unseres Postgres 17-Codebeispiels enthält folgendes:
postgres=# explain analyze with x as materialized (select unique1 from tenk1 b order by unique1)
select count(*) from tenk1 a
where unique1 in (select * from x);
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------- Aggregate (Kosten=987,55..987,56 Zeilen=1 Breite=8) (tatsächliche Zeit=8,777..8,778 Zeilen=1 Schleifen=1)
CTE x
-> Index Only Scan using tenk1_unique1 on tenk1 b (cost=0.29..306.29 rows=10000 width=4) (actual time=0.010..1.095 rows=100
00 loops=1)
Heap Fetches: 0
-> Merge Semi Join (cost=0.31..656.26 rows=10000 width=0) (actual time=0.037..8.024 rows=10000 loops=1)
Merge Cond: (a.unique1 = x.unique1)
-> Index Only Scan using tenk1_unique1 on tenk1 a (cost=0.29..306.29 rows=10000 width=4) (actual time=0.013..1.262 rows
=10000 loops=1)
Heap Fetches: 0
-> CTE Scan on x (cost=0.00..200.00 rows=10000 width=4) (actual time=0.016..3.678 rows=10000 loops=1)
Planning Time: 0.800 ms
Execution Time: 8.899 ms
(11 rows)
Die Abfragepläne in Postgres 16 und Postgres 17 unterscheiden sich erheblich aufgrund dieser Version 17-Verbesserung. Dies ist ein kleiner Beispiel; man kann erkennen, dass die Leistungsverbesserung bei größeren Abfragen signifikant sein wird. Bitte beachten Sie, dass diese Verbesserung nur wirksam ist, wenn die CTE-Subabfrage eine ORDER BY
-Klausel enthält.
Schnelle B-Baum-Indexscans für Skalare Array
In PostgreSQL ist ScalarArrayOpExpr
ein Knotentyp in der Ausführungsplanung, der Abfragen behandelt, die Operationen wie IN
oder ANY
mit Arrays oder Listen von Werten aufweisen. Dies ist besonders nützlich für Abfragen, in denen Sie eine Spalte gegen ein Satz von Werten vergleichen, z.B.: SELECT * FROM table WHERE column = ANY(ARRAY[1, 2, 3]);
.
ScalarArrayOpExpr
ermöglicht es PostgreSQL, Abfragen zu optimieren, die mehrere Vergleiche aufweisen, die IN
oder ANY
verwenden. PostgreSQL 17 hat neue Leistungsverbesserungen eingeführt, um diese Operationen sogar schneller zu machen.
In PostgreSQL 17 wurden bedeutende Verbesserungen an den B-Baum-Indexscans durchgeführt, die die Leistung optimieren, insbesondere für Abfragen mit großen IN
-Listen oder ANY
-Bedingungen. Diese Verbesserungen reduzieren die Anzahl der durch das System durchgeführten Indexscans, was die CPU- und Pufferseitenkontention verringern und somit die schnellere Ausführung von Abfragen bewirken kann.
Eine der wichtigsten Verbesserungen ist in der Behandlung von Skalaren Arrayoperationen (SAOP), die eine effizientere Durchsuchung von B-Baum-Indizes ermöglicht, insbesondere für mehrdimensionale Abfragen. Zum Beispiel kann PostgreSQL 17 bei mehreren Indexspalten (jede mit eigenem IN
-Liste) diese Operationen nun effizienter in einem einzigen Indexscan verarbeiten, anstatt in vorherigen Versionen mehrerer Scans. Dies kann zu Leistungsverbesserungen von 20-30% in CPU-beanspruchten Workloads führen, wo zuvor Seitenzugriffe einengestanden hatten.
Zusätzlich bringt PostgreSQL 17 eine bessere Verwaltung der internen Sperrverfahren, was die Leistung für hohe Konkurrenzlasten weiter verbessert, insbesondere beim Scannen mehrerer Dimensionen innerhalb eines B-Baum-Indexes.
Wir können dies mit einem einfachen Beispiel demonstrieren. Wir werden die selbe tenk1
-Tabelle und Daten verwenden, die wir im vorhergehenden Beispiel aus den Postgres-Regressionssuite verwendet haben.
Unser Beispiel, das zunächst mit Postgres 16 ausgeführt wird:
CREATE TABLE tenk1 (
postgres(# unique1 int4,
postgres(# unique2 int4,
postgres(# two int4,
postgres(# four int4,
postgres(# ten int4,
postgres(# twenty int4,
postgres(# hundred int4,
postgres(# thousand int4,
postgres(# twothousand int4,
postgres(# fivethous int4,
postgres(# tenthous int4,
postgres(# odd int4,
postgres(# even int4,
postgres(# stringu1 name,
postgres(# stringu2 name,
postgres(# string4 name
postgres(# );
CREATE TABLE
postgres=# CREATE INDEX tenk1_unique1 ON tenk1 USING btree(unique1 int4_ops);
CREATE INDEX
postgres=# \copy tenk1 FROM '~/projects/postgres/src/test/regress/data/tenk.data';
COPY 10000
postgres=# EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM tenk1 WHERE unique1 IN (1, 2, 3);
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on tenk1 (cost=14.20..330.12 rows=176 width=244) (actual time=0.138..0.153 rows=3 loops=1)
Recheck Cond: (unique1 = ANY ('{1,2,3}'::integer[]))
Heap Blocks: exact=3
Buffers: shared hit=9
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..14.16 rows=176 width=0) (actual time=0.102..0.102 rows=3 loops=1)
Index Cond: (unique1 = ANY ('{1,2,3}'::integer[]))
Buffers: shared hit=6
Planning:
Buffers: shared hit=2
Planning Time: 0.900 ms
Execution Time: 0.242 ms
(11 rows)
postgres=# SELECT idx_scan, idx_tup_fetch FROM pg_stat_user_tables WHERE relname = 'tenk1';
idx_scan | idx_tup_fetch
----------+---------------
3 | 3
(1 row)
In der vorhergehenden Abfrage kann man sehen, dass der gemeinsame Puffer-Treffer für die IN
-Abfrage 9 betrug und es drei Indexscans brauchte, um die Ergebnisse aus dem Indexscan zu erhalten. In PostgreSQL bezeichnet der Begriff gemeinsamer Treffer eine bestimmte Art von Cache-Treffer, der mit dem Puffer-Management in Verbindung steht. Ein gemeinsamer Treffer tritt auf, wenn PostgreSQL einen Datenblock oder Seite aus dem gemeinsamen Pufferpool zugänglich macht, anstatt von der Festplatte, was die Abfrageleistung verbessert.
Das gleiche Beispiel, diesmal mit Postgres 17 ausgeführt:
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM tenk1 WHERE unique1 IN (1, 2, 3);
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
Bitmap Heap Scan on tenk1 (cost=12.88..24.08 rows=3 width=244) (actual time=0.043..0.054 rows=3 loops=1)
Recheck Cond: (unique1 = ANY ('{1,2,3}'::integer[]))
Heap Blocks: exact=3
Buffers: shared hit=5
-> Bitmap Index Scan on tenk1_unique1 (cost=0.00..12.88 rows=3 width=0) (actual time=0.026..0.026 rows=3 loops=1)
Index Cond: (unique1 = ANY ('{1,2,3}'::integer[]))
Buffers: shared hit=2
Planning:
Buffers: shared hit=59
Planning Time: 0.479 ms
Execution Time: 0.116 ms
(11 rows)
postgres=# SELECT idx_scan, idx_tup_fetch FROM pg_stat_user_tables WHERE relname = 'tenk1';
idx_scan | idx_tup_fetch
----------+---------------
1 | 3
(1 row)
Wie du siehst, ist mit Postgres 17 der gemeinsam genutzte Puffer-Treffer auf 5 reduziert worden, und das Wesentliche ist, dass nur ein Indexscan durchgeführt wird (im Vergleich zu 3 Scans in dem Fall von Postgres 16). Dank dieser Verbesserung in Postgres 17 ist die Leistung von skalaren Arrayoperationen stark verbessert, und Postgres kann von besseren optimierten Abfrageplänen auswählen.
Beibehaltung von Logischen Replikationsslots und Abonnementen während des Upgrades
Die Beibehaltung von logischen Replikationsslots und die Migration von Abonnementabhängigkeiten während des großen Upgrade-Prozesses ist eine weitere logische Replikationsfunktion, die zu PostgreSQL 17 hinzugefügt wurde. Beachte, dass diese Funktion nur dann nützlich sein wird, wenn du von PostgreSQL 17 auf spätere Versionen aktualisierst; dies wird nicht für Upgrades vor Postgres 17 unterstützt. Die Replikationsslots und Replikationsursprünge werden beim Setzen einer logischen Replikationsumgebung erstellt. Allerdings ist diese Information spezifisch für den Knoten, um die Replikationsstatus, den Anwendungsstatus und den WAL-Übertragungsstatus aufzunehmen, sodass sie nicht Teil des Upgrade-Prozesses sind. Sobald der veröffentlichte Knoten aktualisiert wurde, muss der Benutzer diese Objekte manuell aufbauen.
Der pg_upgrade-Prozess ist in PostgreSQL 17 verbessert worden, um auf diese internen Objekte zu verweisen und sie neu zu bauen; diese Funktionalität ermöglicht die automatische Wiederaufnahme der Replikation, wenn ein Knoten, der logische Replikation nutzt, aktualisiert wird. Früher mussten Benutzer bei der Durchführung eines großen Versionenupgrades logische Replikationsslots ablegen, was sie dazu zwang, nach dem Upgrade die Daten mit den Abonnenten neu zu synchronisieren. Dies verursachte Komplexität und verlängerte die Downtime während der Upgrades.
Beim Upgrade des Publisher-Clusters müssen Sie die folgenden Schritte befolgen:
- Stellen Sie sicher, dass alle Abonnements des Publishers vorübergehend deaktiviert sind, indem Sie ein
ALTER SUBSCRIPTION….DISABLE
ausführen. Diese werden nach Abschluss des Upgrade-Prozesses wieder aktiviert. - Setzen Sie das
wal_level
des neuen Clusters auflogical
. - Der
max_replication_slots
im neuen Cluster muss auf einen Wert eingestellt sein, der größer oder gleich den Replikations-Slots im alten Cluster ist. - Die von den Slots verwendeten Output-Plugins müssen im neuen Cluster installiert werden.
- Alle Änderungen vom alten Cluster sind bereits vor dem Upgrade auf den Zielcluster repliziert worden.
- Alle Slots im alten Cluster müssen nutzbar sein; dies können Sie sicherstellen, indem Sie die konfliktfreien Spalten in der pg_replication_slots-Ansicht überprüfen. Konflikte sollten für alle Slots im alten Cluster auf „False“ stehen.
- Keine Slots im neuen Cluster sollten einen Wert von
false
in derTemporary
-Spalte derpg_replication_slots
-Ansicht haben. Es sollten keine dauerhaften logischen Replikations-Slots im neuen Cluster vorhanden sein.
Der pg_upgrade
-Prozess zum Upgrade der Replikations-Slots führt zu einem Fehler, wenn eine der oben genannten Voraussetzungen nicht erfüllt ist.
Fazit
Mit PostgreSQL 17 bleibt die Community konzentriert darauf, PostgreSQL weiterhin besser, skalierbar, sicher und enterprise-fähig zu machen. Postgres 17 verbessert auch die Entwickler Erfahrung, indem es neue Features für Kompatibilität hinzufügt und bestehende Features stärker und robuster macht.
Außerhalb der Version 17 wird PostgreSQL weiterentwickelt, verbessert und besser performant, um auf die Bedürfnisse von Unternehmensanwendungen abzusprechen, die skalierbare Datenbanken benötigen. Die Skalierbarkeit (horizontal und vertikal) hat sich im Verlaufe der Jahre verbessert, aber es gibt definitiv Potential, um die horizontale Fähigkeit durch das Hinzufügen von Sharding-Fähigkeiten zu PostgreSQL weiterzuentwickeln. Wir werden mehr Verbesserungen in der logischen Replikation sehen, mit weiteren Verbesserungen im Bereich der DDL-Replikation oder der Replikation fehlender Objekte (wie Sequenzen) und einer besseren Node-Verwaltung. Die Community erkennt auch die Notwendigkeit, PostgreSQL kompatibler zu machen, daher die Verbesserungen des Befehls MERGE
in Postgres 17 und die Pläne für weitere Kompatibilitätsfunktionen über Postgres 17 hinaus.
Source:
https://dzone.com/articles/postgresql-17-a-major-step-forward-in-performance