Megosztás a következőn keresztül:


Táblák terjesztése és módosítása az Azure Cosmos DB for PostgreSQL-ben

Fontos

Az Azure Cosmos DB for PostgreSQL már nem támogatott új projektek esetén. Ne használja ezt a szolgáltatást új projektekhez. Ehelyett használja az alábbi két szolgáltatás egyikét:

  • Az Azure Cosmos DB for NoSQL használata nagy léptékű forgatókönyvekhez tervezett elosztott adatbázis-megoldáshoz 99,999% rendelkezésre állási szolgáltatásiszint-szerződéssel (SLA), azonnali automatikus skálázással és automatikus feladatátvétellel több régióban.

  • Használja az Azure Database For PostgreSQL Rugalmas fürtök funkcióját a megosztott PostgreSQL-hez a nyílt forráskódú Citus-bővítmény használatával.

Táblák elosztása

Elosztott tábla létrehozásához először meg kell határoznia a táblázatsémát. Ehhez ugyanúgy definiálhat egy táblát a CREATE TABLE utasítással, mint egy normál PostgreSQL-táblával.

CREATE TABLE github_events
(
    event_id bigint,
    event_type text,
    event_public boolean,
    repo_id bigint,
    payload jsonb,
    repo jsonb,
    actor jsonb,
    org jsonb,
    created_at timestamp
);

Ezután a create_distributed_table() függvénnyel megadhatja a tábla terjesztési oszlopát, és létrehozhatja a feldolgozó szegmenseket.

SELECT create_distributed_table('github_events', 'repo_id');

A függvényhívás tájékoztatja az Azure Cosmos DB for PostgreSQL-t, hogy a github_events táblát el kell osztani a repo_id oszlopban (az oszlopérték kivonatolásával).

Alapértelmezés szerint összesen 32 szegmenst hoz létre, ahol minden szegmens egy kivonatterület egy részét birtokolja, és az alapértelmezett citus.shard_replication_factor konfigurációs érték alapján replikálódik. A munkavégzőn létrehozott szegmensreplikák ugyanazokkal a táblasémával, indexekkel és kényszerdefiníciókkal rendelkeznek, mint a koordinátor táblája. A replikák létrehozása után a függvény a koordinátoron menti az összes elosztott metaadatot.

Minden létrehozott szegmenshez egyedi szegmensazonosító tartozik, és minden replikája ugyanazzal a szegmensazonosítóval rendelkezik. A szegmensek a feldolgozó csomóponton "tablename_shardid" nevű normál PostgreSQL-táblákként jelennek meg, ahol a táblanév az elosztott tábla neve, a szegmensazonosító pedig a hozzárendelt egyedi azonosító. A munkavégző postgres példányokhoz kapcsolódva megtekintheti vagy futtathatja a parancsokat az egyes szegmenseken.

Most már készen áll arra, hogy adatokat szúrjon be az elosztott táblába, és lekérdezéseket futtasson rajta. A jelen szakaszban használt felhasználó által definiált függvényről (UDF) is többet megtudhat a tábla és darabolás DDL-referenciában.

Referenciatáblák

Az előző metódus több vízszintes szegmensbe osztja el a táblákat. Egy másik lehetőség a táblák elosztása egyetlen szegmensbe, és a szegmens replikálása minden munkavégző csomópontra. Az így elosztott táblákat referenciatábláknak nevezzük. Olyan adatok tárolására szolgálnak, amelyeket egy fürt több csomópontjának gyakran kell elérnie.

A referenciatáblák gyakori jelöltjei a következők:

  • Kisebb táblák, amelyeket nagyobb elosztott táblákkal kell összekapcsolni.
  • Több-bérlős alkalmazások olyan táblái, amelyek nem rendelkeznek bérlőazonosító oszlopmal, vagy amelyek nincsenek bérlőhöz társítva. (Vagy a migrálás során, még a bérlőkhöz társított táblák esetében is.)
  • Azok a táblák, amelyek több oszlopra kiterjedő egyedi korlátozásokat igényelnek, és elég kicsik.

Tegyük fel például, hogy egy több-bérlős e-kereskedelmi webhelynek ki kell számítania az egyik üzletében végrehajtott tranzakciók forgalmi adóját. Az adóinformációk nem egy bérlőre vonatkoznak. Érdemes egy megosztott táblába helyezni. Az USA-központú referenciatáblák a következőképpen nézhetnek ki:

-- a reference table

CREATE TABLE states (
  code char(2) PRIMARY KEY,
  full_name text NOT NULL,
  general_sales_tax numeric(4,3)
);

-- distribute it to all workers

SELECT create_reference_table('states');

Most olyan lekérdezések, mint például egy bevásárlókocsi adójának kiszámítása, csatlakozhatnak a states táblához hálózati terhelés nélkül, és hozzáadhatnak egy idegen kulcsot az állapotkódhoz a jobb ellenőrzés érdekében.

Amellett, hogy egyetlen replikált szegmensként oszt el egy táblát, az create_reference_table UDF referenciatábláként jelöli meg az Azure Cosmos DB for PostgreSQL metaadattábláiban. Az Azure Cosmos DB for PostgreSQL automatikusan kétfázisú véglegesítéseket (2PC) hajt végre az így megjelölt táblák módosításaihoz, ami erős konzisztenciagaranciát biztosít.

További példa a referenciatáblák használatára: a több-bérlős adatbázis oktatóanyaga.

Koordinátor adatainak terjesztése

Ha egy meglévő PostgreSQL-adatbázist átalakítanak egy fürt koordinátorcsomópontjaivá, a táblákban lévő adatok hatékonyan és minimális megszakítással terjeszthetők egy alkalmazás számára.

A create_distributed_table korábban ismertetett függvény üres és nem üres táblákon egyaránt működik, és az utóbbi esetében automatikusan elosztja a táblasorokat a fürtön belül. Tudja, hogy az adatok másolása az "ÉRTESÍTÉS: Adatok másolása a helyi táblából..." üzenet jelenlétével történik-e. Például:

CREATE TABLE series AS SELECT i FROM generate_series(1,1000000) i;
SELECT create_distributed_table('series', 'i');
NOTICE:  Copying data from local table...
 create_distributed_table
 --------------------------

 (1 row)

A tábla írásai le lesznek tiltva az adatok migrálása során, a függőben lévő írások pedig elosztott lekérdezésekként lesznek kezelve a függvény véglegesítése után. (Ha a függvény meghiúsul, a lekérdezések ismét helyiek lesznek.) Az olvasások a szokásos módon folytatódhatnak, és a függvény véglegesítése után elosztott lekérdezésekké válnak.

Az A és a B táblák elosztásakor, ahol az A idegen kulcsot tartalmaz A-nak, először ossza el a B kulcs céltáblát. Ha nem megfelelő sorrendben végzi el, a következő hibát okozza:

ERROR:  cannot create foreign key constraint
DETAIL:  Referenced table must be a distributed table or a reference table.

Ha nem lehet a megfelelő sorrendben elosztani, akkor dobja el az idegen kulcsokat, ossza el a táblákat, és hozza létre újra az idegen kulcsokat.

Amikor adatokat migrál egy külső adatbázisból, például az Amazon RDS-ből az Azure Cosmos DB for PostgreSQL-be, először hozzon létre elosztott táblákat az Azure Cosmos DB for PostgreSQL-ben a create_distributed_table segítségével, majd másolja az adatokat a táblába. Az elosztott táblákba való másolással elkerülhető, hogy a koordinátor csomóponton elfogyjon a szabad terület.

Táblák áthelyezése

A kolokáció azt jelenti, hogy a kapcsolódó információk ugyanazon gépeken kerülnek elhelyezésre. Hatékony lekérdezéseket tesz lehetővé, miközben kihasználja a teljes adatkészlet horizontális méretezhetőségét. További információ: colocation.

A táblák csoportokba vannak helyezve. A tábla helycsoport-hozzárendelésének manuális vezérléséhez használja a tábla nem kötelező colocate_with paraméterét create_distributed_table. Ha nem érdekli a tábla helye, hagyja ki ezt a paramétert. Alapértelmezés szerint az az érték 'default', amely a táblát bármely más alapértelmezett, azonos terjesztési oszloptípussal, szegmensszámmal és replikációs tényezővel rendelkező társhelytáblával csoportosítja. Ha meg szeretné szakítani vagy frissíteni ezt az implicit elhelyezést, használhatja a update_distributed_table_colocation()-t.

-- these tables are implicitly co-located by using the same
-- distribution column type and shard count with the default
-- co-location group

SELECT create_distributed_table('A', 'some_int_col');
SELECT create_distributed_table('B', 'other_int_col');

Ha egy új tábla nem kapcsolódik a leendő implicit társhelycsoport többi tagjához, adja meg colocated_with => 'none'.

-- not co-located with other tables

SELECT create_distributed_table('A', 'foo', colocate_with => 'none');

A nem kapcsolódó táblák saját társhelycsoportokra való felosztása javítja a szegmensek újraegyensúlyozási teljesítményét, mivel az ugyanabban a csoportban lévő szegmenseket együtt kell áthelyezni.

Ha a táblák valóban kapcsolódnak egymáshoz (például amikor össze vannak kapcsolva), érdemes lehet őket egy helyre elhelyezni. A megfelelő közös elhelyezés előnyei fontosabbak, mint bármilyen kiegyensúlyozási terhelési többlet.

Több tábla explicit elhelyezéséhez ossza el az egyiket, majd helyezze a többit a társhelycsoportba. Példa:

-- distribute stores
SELECT create_distributed_table('stores', 'store_id');

-- add to the same group as stores
SELECT create_distributed_table('orders', 'store_id', colocate_with => 'stores');
SELECT create_distributed_table('products', 'store_id', colocate_with => 'stores');

A helycsoportokkal kapcsolatos információkat a pg_dist_colocation tábla tárolja, a pg_dist_partition pedig azt, hogy mely táblák melyik csoportokhoz vannak rendelve.

Táblák törlése

Az elosztott táblák eltávolításához használhatja a szabványos PostgreSQL DROP TABLE parancsot. A hagyományos táblákhoz hasonlóan a DROP TABLE eltávolítja a céltáblához tartozó összes indexet, szabályt, eseményindítót és korlátozást. Emellett a darabokat a munkavégző csomópontokra helyezi, és megtisztítja a metaadataikat.

DROP TABLE github_events;

Táblák módosítása

Az Azure Cosmos DB for PostgreSQL automatikusan propagálja a DDL-utasítások számos típusát. Az elosztott tábla módosítása a koordinátorcsomóponton a munkavégzők szeleteit is frissíti. Más DDL-utasítások manuális propagálást igényelnek, és bizonyos egyéb utasítások nem engedélyezettek, például amelyek módosítanák a terjesztési oszlopokat. Ha olyan DDL-t próbál futtatni, amely nem jogosult az automatikus propagálásra, hibát jelez, és változatlanul hagyja a koordinátorcsomópont tábláit.

Íme egy áttekintés a propagált DDL-utasítások kategóriáiról.

Oszlopok hozzáadása/módosítása

Az Azure Cosmos DB for PostgreSQL automatikusan propagálja a legtöbb ALTER TABLE-parancsot . Az oszlopok hozzáadása vagy az alapértelmezett értékek módosítása ugyanúgy működik, mint egy egygépes PostgreSQL-adatbázisban:

-- Adding a column

ALTER TABLE products ADD COLUMN description text;

-- Changing default value

ALTER TABLE products ALTER COLUMN price SET DEFAULT 7.77;

A meglévő oszlopok jelentős módosításai, például átnevezése vagy adattípusának módosítása is rendben van. A terjesztési oszlop adattípusa azonban nem módosítható. Ez az oszlop határozza meg, hogy a táblaadatok hogyan oszlanak el a fürtben, és az adattípus módosításához az adatok áthelyezésére van szükség.

Ennek megkísérlése hibát okoz:

-- assumining store_id is the distribution column
-- for products, and that it has type integer

ALTER TABLE products
ALTER COLUMN store_id TYPE text;

/*
ERROR:  XX000: cannot execute ALTER TABLE command involving partition column
LOCATION:  ErrorIfUnsupportedAlterTableStmt, multi_utility.c:2150
*/

Korlátozások hozzáadása/eltávolítása

Az Azure Cosmos DB for PostgreSQL használatával továbbra is élvezheti a relációs adatbázisok biztonságát, beleértve az adatbázis-korlátozásokat is (lásd a PostgreSQL-dokumentációt). Az elosztott rendszerek jellegéből adódóan az Azure Cosmos DB for PostgreSQL nem hivatkozik kereszthivatkozásokra az egyediségi korlátozásokra vagy a feldolgozó csomópontok közötti hivatkozási integritásra.

A társított elosztott táblák közötti idegen kulcs beállításához mindig vegye bele a kulcsba az elosztó oszlopot. A disztribúciós oszlop felvétele magában foglalhatja a kulcsvegyület elkészítését is.

Ilyen esetekben idegen kulcsok hozhatók létre:

  • két helyi (nem elosztott) tábla között,
  • két referenciatábla között,
  • két együtt elhelyezkedő elosztott tábla között, ha a kulcs tartalmazza az elosztási oszlopot, vagy
  • hivatkozási táblára hivatkozó elosztott táblaként

A referenciatábláktól az elosztott táblákig nem támogatottak az idegen kulcsok.

Feljegyzés

Az elsődleges kulcsoknak és az egyediségi korlátozásoknak tartalmazniuk kell a terjesztési oszlopot. Ha nem elosztási oszlopba adja őket, hibaüzenet jelenik meg

Ez a példa bemutatja, hogyan hozhat létre elsődleges és idegen kulcsokat elosztott táblákon:

--
-- Adding a primary key
-- --------------------

-- We'll distribute these tables on the account_id. The ads and clicks
-- tables must use compound keys that include account_id.

ALTER TABLE accounts ADD PRIMARY KEY (id);
ALTER TABLE ads ADD PRIMARY KEY (account_id, id);
ALTER TABLE clicks ADD PRIMARY KEY (account_id, id);

-- Next distribute the tables

SELECT create_distributed_table('accounts', 'id');
SELECT create_distributed_table('ads',      'account_id');
SELECT create_distributed_table('clicks',   'account_id');

--
-- Adding foreign keys
-- -------------------

-- Note that this can happen before or after distribution, as long as
-- there exists a uniqueness constraint on the target column(s) which
-- can only be enforced before distribution.

ALTER TABLE ads ADD CONSTRAINT ads_account_fk
  FOREIGN KEY (account_id) REFERENCES accounts (id);
ALTER TABLE clicks ADD CONSTRAINT clicks_ad_fk
  FOREIGN KEY (account_id, ad_id) REFERENCES ads (account_id, id);

Hasonlóképpen vegye fel a terjesztési oszlopot az egyediségi korlátozások közé:

-- Suppose we want every ad to use a unique image. Notice we can
-- enforce it only per account when we distribute by account id.

ALTER TABLE ads ADD CONSTRAINT ads_unique_image
  UNIQUE (account_id, image_url);

A nem null értékű kényszerek bármely oszlopra (eloszlásra vagy sem) alkalmazhatók, mert nem igényelnek kereséseket a feldolgozók között.

ALTER TABLE ads ALTER COLUMN image_url SET NOT NULL;

ÉRVÉNYTELEN korlátozások használata

Bizonyos helyzetekben hasznos lehet kényszereket kényszeríteni az új sorokra, miközben a meglévő nem megfelelő sorok változatlanok maradnak. Az Azure Cosmos DB for PostgreSQL támogatja ezt a funkciót a CHECK kényszerekhez és az idegen kulcsokhoz a PostgreSQL "NEM ÉRVÉNYES" kényszermegjelölésével.

Vegyük például azt az alkalmazást, amely egy referenciatáblában tárolja a felhasználói profilokat.

-- we're using the "text" column type here, but a real application
-- might use "citext" which is available in a postgres contrib module

CREATE TABLE users ( email text PRIMARY KEY );
SELECT create_reference_table('users');

Idővel képzelje el, hogy néhány cím nélküli elem kerül a táblázatba.

INSERT INTO users VALUES
   ('foo@example.com'), ('hacker12@aol.com'), ('lol');

Szeretnénk ellenőrizni a címeket, de a PostgreSQL általában nem teszi lehetővé, hogy olyan CHECK kényszert adjunk hozzá, amely nem felel meg a meglévő soroknak. Ez azonban nem teszi lehetővé a érvénytelenként megjelölt kényszert:

ALTER TABLE users
ADD CONSTRAINT syntactic_email
CHECK (email ~
   '^[a-zA-Z0-9.!#$%&''*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$'
) NOT VALID;

Az új sorok mostantól védettek.

INSERT INTO users VALUES ('fake');

/*
ERROR:  new row for relation "users_102010" violates
        check constraint "syntactic_email_102010"
DETAIL:  Failing row contains (fake).
*/

Később, csúcsidőn kívüli időszakban az adatbázis-rendszergazda megpróbálhatja kijavítani a hibás sorokat, és újraértékelni a kényszert.

-- later, attempt to validate all rows
ALTER TABLE users
VALIDATE CONSTRAINT syntactic_email;

A PostgreSQL dokumentációja az ALTER TABLE szakaszban további információt tartalmaz a NEM ÉRVÉNYES ÉS ÉRVÉNYESÍTETT KORLÁTOZÁSról.

Indexek hozzáadása/eltávolítása

Az Azure Cosmos DB for PostgreSQL támogatja az indexek hozzáadását és eltávolítását:

-- Adding an index

CREATE INDEX clicked_at_idx ON clicks USING BRIN (clicked_at);

-- Removing an index

DROP INDEX clicked_at_idx;

Az index hozzáadása írási zárolást igényel, ami nem kívánatos lehet egy több-bérlős "rekordrendszerben". Az alkalmazás állásidejének minimalizálása érdekében hozza létre az indexet egyidejűleg . Ez a módszer több teljes munkát igényel, mint egy szabványos index build, és több időt vesz igénybe. Mivel azonban lehetővé teszi a normál műveletek folytatását az index létrehozása során, ez a módszer hasznos új indexek éles környezetben való hozzáadásához.

-- Adding an index without locking table writes

CREATE INDEX CONCURRENTLY clicked_at_idx ON clicks USING BRIN (clicked_at);

Típusok és függvények

Az egyéni SQL-típusok és a felhasználó által definiált függvények létrehozása a feldolgozó csomópontokra is kiterjeszthető. Az ilyen adatbázis-objektumok elosztott műveletekkel végzett tranzakcióban való létrehozása azonban kompromisszumokkal jár.

Az Azure Cosmos DB for PostgreSQL párhuzamosítja az olyan műveleteket, mint create_distributed_table(), a shardok között feldolgozónként több kapcsolat használatával. Míg egy adatbázis-objektum létrehozásakor az Azure Cosmos DB for PostgreSQL egy feldolgozói kapcsolat használatával propagálja azt a feldolgozó csomópontokra. A két művelet egyetlen tranzakcióban való kombinálása problémákat okozhat, mivel a párhuzamos kapcsolatok nem fogják látni az egyetlen kapcsolaton keresztül létrehozott, de még nem véglegesített objektumot.

Fontolja meg egy tranzakcióblokkot, amely létrehoz egy típust, egy táblát, betölti az adatokat, és elosztja a táblát:

BEGIN;

-- type creation over a single connection:
CREATE TYPE coordinates AS (x int, y int);
CREATE TABLE positions (object_id text primary key, position coordinates);

-- data loading thus goes over a single connection:
SELECT create_distributed_table(‘positions’, ‘object_id’);

SET client_encoding TO 'UTF8';
\COPY positions FROM ‘positions.csv’

COMMIT;

A Citus 11.0 előtt a Citus elhalasztotta a típus létrehozását a feldolgozó csomópontokon, és külön véglegesíti azt az elosztott tábla létrehozásakor. Ez lehetővé tette az create_distributed_table() adatainak párhuzamos másolását. Azt is jelentette azonban, hogy a típus nem mindig volt jelen a Citus-feldolgozó csomópontokon – vagy ha a tranzakció visszagördült, a típus a feldolgozó csomópontokon marad.

A Citus 11.0-val az alapértelmezett viselkedés megváltozik a koordinátor és a feldolgozó csomópontok sémakonzisztenciájának rangsorolása érdekében. Az új viselkedésnek hátránya van: ha az objektumpropagálás egy párhuzamos parancs után történik ugyanabban a tranzakcióban, akkor a tranzakció már nem hajtható végre, amint azt az alábbi kódblokkban található HIBA kiemeli:

BEGIN;
CREATE TABLE items (key text, value text);
-- parallel data loading:
SELECT create_distributed_table(‘items’, ‘key’);
SET client_encoding TO 'UTF8';
\COPY items FROM ‘items.csv’
CREATE TYPE coordinates AS (x int, y int);

ERROR:  cannot run type command because there was a parallel operation on a distributed table in the transaction

Ha ezt a problémát tapasztalja, két egyszerű megkerülő megoldás létezik:

  1. Használja a citus.create_object_propagation beállítást automatic-re a típus létrehozásának késleltetéséhez ebben a helyzetben, ilyen esetben előfordulhat, hogy némi inkonzisztencia merül fel, hogy mely adatbázis-objektumok léteznek a különböző csomópontokon.
  2. A(z) citus.multi_shard_modify_mode használatával a sequential beállításánál letilthatja a csomópontonkénti párhuzamosságot. Előfordulhat, hogy ugyanabban a tranzakcióban lassabb az adatbetöltés.

Következő lépések