sql >> Database >  >> RDS >> PostgreSQL

Uw gegevens sharden met PostgreSQL 11

Versie 10 van PostgreSQL heeft de declaratieve tabelpartitionering toegevoegd feature.In versie 11 (momenteel in bèta) kun je dit combineren met buitenlandse datawrappers , wat een mechanisme biedt om uw tabellen native te sharden over meerdere PostgreSQL-servers.

Declaratieve partitionering

Overweeg een tabel waarin de dagelijkse minimum- en maximumtemperaturen van steden voor elke dag zijn opgeslagen:

CREATE TABLE temperatures (
    at      date,
    city    text,
    mintemp integer,
    maxtemp integer
);

De tabelspecificatie is opzettelijk verstoken van kolombeperkingen en primaire sleutel om het eenvoudig te houden - we zullen deze later toevoegen.

Het is heel gebruikelijk om te ontdekken dat in veel toepassingen de meest recente gegevens vaker worden gebruikt. Denk aan het huidige boekjaar, deze maand, het afgelopen uur enzovoort. Naarmate onze tabel "temperaturen" groeit, is het logisch om de oude gegevens naar een andere tabel met dezelfde structuur te verplaatsen. We kunnen dit bijvoorbeeld doen:

CREATE TABLE temperatures_2017 (LIKE temperatures);
INSERT INTO temperatures_2017 SELECT * FROM temperatures WHERE
	extract(year from at) = 2017;
DELETE FROM temperatures WHERE extract(year from at) = 2017;

om alle vermeldingen van het jaar 2017 naar een andere tabel te verplaatsen. Hierdoor blijft de hoofdtabel met "temperaturen" kleiner en sneller voor de toepassing om mee te werken. Als een bonus, als u nu oude gegevens moet verwijderen, kunt u dit doen zonder het invoegen van inkomende gegevens in de hoofd-/huidige tabel te vertragen, omdat de oude gegevens in een andere tabel.

Maar het hebben van meerdere, verschillende tabellen betekent dat de applicatiecode nu moet veranderen. Als het toegang moet krijgen tot oudere gegevens, bijvoorbeeld de jaarlijkse minimum- en maximumtemperaturen van een stad, moet het nu uitvinden welke tabellen in het schema aanwezig zijn, elk ervan opvragen en de resultaten van elke tabel combineren. Kunnen we dit doen zonder de applicatiecode te wijzigen?

Partitionering maakt dit mogelijk. In PostgreSQL 10 kunt u de tabel 'temperaturen' als volgt maken:

CREATE TABLE temperatures (
    at      date,
    city    text,
    mintemp integer,
    maxtemp integer
)
PARTITION BY RANGE (at);

Dit maakt van "temperatures" een partitie-mastertabel en vertelt PostgreSQL dat we meerdere gepartitioneerde tabellen gaan maken die niet-overlappende gegevens opslaan, elk met een andere set "at" -waarden. De hoofdtabel zelf bevat geen gegevens, maar kan worden opgevraagd en ingevoegd door de toepassing - die geen weet heeft van de onderliggende partities die de actuele gegevens bevatten.

En hier zijn onze partities:

CREATE TABLE temperatures_2017
    PARTITION OF temperatures
    FOR VALUES FROM ('2017-01-01') TO ('2018-01-01');

CREATE TABLE temperatures_2018
    PARTITION OF temperatures
    FOR VALUES FROM ('2018-01-01') TO ('2019-01-01');

We hebben nu twee tabellen, een met gegevens voor 2017 en een andere voor 2018. Merk op dat de waarde "van" inclusief is, maar de waarde "naar" niet. Laten we het eens proberen:

temp=# INSERT INTO temperatures (at, city, mintemp, maxtemp)
temp-#        VALUES ('2018-08-03', 'London', 63, 90);
INSERT 0 1
temp=# INSERT INTO temperatures (at, city, mintemp, maxtemp)
temp-#        VALUES ('2017-08-03', 'London', 59, 70);
INSERT 0 1
temp=# SELECT * FROM temperatures;
     at     |  city  | mintemp | maxtemp
------------+--------+---------+---------
 2017-08-03 | London |      59 |      70
 2018-08-03 | London |      63 |      90
(2 rows)

temp=# SELECT * FROM temperatures_2017;
     at     |  city  | mintemp | maxtemp
------------+--------+---------+---------
 2017-08-03 | London |      59 |      70
(1 row)

temp=# SELECT * FROM temperatures_2018;
     at     |  city  | mintemp | maxtemp
------------+--------+---------+---------
 2018-08-03 | London |      63 |      90
(1 row)

De "toepassing" kan invoegen in en selecteren uit de hoofdtabel, maar PostgreSQL stuurt de feitelijke gegevens naar de juiste onderliggende tabellen. (Oh en tussen haakjes, die temperaturen zijn echt!)

Indexen en beperkingen

Indexen en tabel- en kolombeperkingen worden feitelijk gedefinieerd op het partitietabelniveau, omdat daar de feitelijke gegevens zich bevinden. U kunt deze instellen tijdens het maken van de partitietabel:

CREATE TABLE temperatures_2017
    PARTITION OF temperatures (
        mintemp NOT NULL,
        maxtemp NOT NULL,
        CHECK (mintemp <= maxtemp),
        PRIMARY KEY (at, city)
    )
    FOR VALUES FROM ('2017-01-01') TO ('2018-01-01');

Met PostgreSQL 11 kunt u indexen definiëren op de bovenliggende tabel en indexen maken op bestaande en toekomstige partitietabellen. Lees hier meer.

Foreign Data Wrapper

De Foreign Data Wrapper-functionaliteit bestaat al enige tijd in Postgres. Met PostgreSQL kunt u via dit mechanisme toegang krijgen tot gegevens die zijn opgeslagen op andere servers en systemen. Waar we in geïnteresseerd zijn, is "postgres_fdw", waarmee we toegang krijgen tot de ene Postgres-server vanaf een andere.

"postgres_fdw" is een extensie die aanwezig is in de standaarddistributie, die kan worden geïnstalleerd met het reguliere CREATE EXTENSION-commando:

CREATE EXTENSION postgres_fdw;

Laten we aannemen dat u een andere PostgreSQL-server "box2" heeft met een database met de naam "box2db". U kunt hiervoor een "buitenlandse server" maken:

CREATE SERVER box2 FOREIGN DATA WRAPPER postgres_fdw
    OPTIONS (host 'box2', dbname 'box2db');

Laten we ook onze gebruiker "alice" (de gebruiker waarmee u bent ingelogd) toewijzen aan box2 gebruiker "box2alice". Hierdoor kan "alice" "box2alice" zijn bij toegang tot externe tabellen:

CREATE USER MAPPING FOR alice SERVER box2
    OPTIONS (user 'box2alice');

Je hebt nu toegang tot tabellen (ook views, matviews etc) op box2. Maak eerst een tafel op box2 en vervolgens een "buitenlandse tafel" op uw server. De buitenlandse tafel bevat geen feitelijke gegevens, maar dient als een proxy voor toegang tot de tableon-box2.

-- on box2
CREATE TABLE foo (a int);

-- on your server
IMPORT FOREIGN SCHEMA public LIMIT TO (foo)
    FROM SERVER box2 INTO public;

De vreemde tafel in uw server kan op dezelfde manier deelnemen aan transacties als normale tafels. Applicaties hoeven niet te weten dat de tabellen waarmee het interageert lokaal of buitenlands zijn - hoewel als uw app een SELECT uitvoert die veel rijen uit een vreemde tabel kan halen, dit de zaken kan vertragen. In Postgres 10 zijn verbeteringen aangebracht voor het naar beneden duwen van joins en aggregeert naar de externe server.

Partitionering en FDW combineren

En nu het leuke gedeelte:partities instellen op externe servers.

Laten we eerst de fysieke partitietabel op box2 maken:

-- on box2
CREATE TABLE temperatures_2016 (
    at      date,
    city    text,
    mintemp integer,
    maxtemp integer
);

En maak dan de partitie op je server aan als een vreemde tabel:

CREATE FOREIGN TABLE temperatures_2016
    PARTITION OF temperatures
    FOR VALUES FROM ('2016-01-01') TO ('2017-01-01')
    SERVER box2;

U kunt nu vanaf uw eigen server invoegen en opvragen:

temp=# INSERT INTO temperatures (at, city, mintemp, maxtemp)
temp-#     VALUES ('2016-08-03', 'London', 63, 73);
INSERT 0 1
temp=# SELECT * FROM temperatures ORDER BY at;
     at     |  city  | mintemp | maxtemp
------------+--------+---------+---------
 2016-08-03 | London |      63 |      73
 2017-08-03 | London |      59 |      70
 2018-08-03 | London |      63 |      90
(3 rows)

temp=# SELECT * FROM temperatures_2016;
     at     |  city  | mintemp | maxtemp
------------+--------+---------+---------
 2016-08-03 | London |      63 |      73
(1 row)

Daar heb je het! Het is nieuw in versie 11 om rijen in een externe partitie in te voegen. Met deze functie kunt u uw gegevens nu logisch (partities) en fysiek (FDW) laten opslaan.

Gegevensbeheer

Commando's zoals VACUUM en ANALYZE werken zoals je zou verwachten met partitiehoofdtabellen - alle lokale onderliggende tabellen zijn onderhevig aan VACUUM en ANALYSE. Partities kunnen worden losgemaakt, het zijn gegevens die worden gemanipuleerd zonder de partitiebeperking en vervolgens opnieuw worden gekoppeld. Partitioneer onderliggende tabellen zelf kunnen worden gepartitioneerd.

Het verplaatsen van gegevens ("opnieuw harden") kan worden gedaan met gewone SQL-instructies (invoegen, verwijderen, kopiëren enz.). Partitie-lokale indexen en triggers kunnen worden gemaakt.

Het toevoegen van redundantie aan uw shards is eenvoudig te realiseren met logische of streamingreplicatie.


  1. Hoe het verschil tussen twee datums in MySQL te berekenen?

  2. Regex gebruiken in WHERE in Postgres

  3. SQL Server 2014:Native back-upversleuteling

  4. `pg_tblspc` ontbreekt na installatie van de nieuwste versie van OS X (Yosemite of El Capitan)