Toto je pokračování mého předchozího příspěvku na blogu, kde jsem se dotkl tématu PostgreSQL Extensions. Rozšíření PostgreSQL jsou plug and play sada vylepšení, která přidávají další sadu funkcí do clusteru PostgreSQL. Některé z těchto funkcí jsou tak jednoduché jako čtení nebo zápis do externí databáze, zatímco jiné mohou představovat sofistikované řešení pro implementaci replikace databáze, monitorování atd.
PostgreSQL se v průběhu let vyvinul z jednoduchého open source ORDBMS na výkonný databázový systém s více než 30 lety aktivního vývoje nabízející spolehlivost, výkon a všechny funkce vyhovující ACID. S PostgreSQL 12 vydaným před několika měsíci je tento databázový software pouze větší, lepší a rychlejší.
Příležitostně bylo potřeba přidat rozšíření do clusteru PostgreSQL, aby se dosáhlo vylepšené funkčnosti, která nebyla v nativním kódu k dispozici, protože buď nebyla vyvinuta kvůli časové tísni nebo kvůli nedostatečným důkazům o databázi okrajových případů problémy. Budu diskutovat o několika mých oblíbených rozšířeních bez konkrétního pořadí, s několika ukázkami, které používají vývojáři a správci databází.
Některá z těchto rozšíření mohou vyžadovat, aby byla zahrnuta v parametru serveru shared_preload_libraries jako seznam oddělený čárkami, který se má předem načíst při spuštění serveru. Ačkoli je většina rozšíření zahrnuta v modulu contrib zdrojového kódu, některá je třeba stáhnout z externího webu věnovaného pouze rozšířením PostgreSQL s názvem PostgreSQL Extension Network.
V této dvoudílné sérii blogů probereme rozšíření používaná pro přístup k datům (postgres_fwd) a zmenšení nebo archivaci databází (pg_partman). Další rozšíření budou probrána v druhé části.
postgres_fdw
postgres_fdw je cizí rozšíření obálky dat, které lze použít pro přístup k datům uloženým na externích serverech PostgreSQL. Toto rozšíření je podobné staršímu rozšíření zvanému dblink, ale od svého předchůdce se liší tím, že nabízí syntaxi vyhovující standardům a lepší výkon.
Důležitými součástmi postgres_fdw jsou server, mapování uživatelů a cizí tabulka. Ke skutečným nákladům na provádění dotazů proti vzdáleným serverům se připočítává menší režie, což je režie komunikace. Rozšíření postgres_fdw je také schopno komunikovat se vzdáleným serverem s verzí až do PostgreSQL 8.3, takže je zpětně kompatibilní s dřívějšími verzemi.
Ukázka
Ukázka ukáže připojení z PostgreSQL 12 k databázi PostgreSQL 11. Nastavení pg_hba.conf již bylo nakonfigurováno, aby spolu servery mluvily. Řídicí soubory rozšíření je třeba načíst do sdíleného domovského adresáře PostgreSQL před vytvořením rozšíření z Uvnitř clusteru PostgreSQL.
Vzdálený server:
$ /usr/local/pgsql-11.3/bin/psql -p 5432 -d db_replica postgres
psql (11.3)
Type "help" for help.
db_replica=# create table t1 (sno integer, emp_id text);
CREATE TABLE
db_replica=# \dt t1
List of relations
Schema | Name | Type | Owner
--------+------+-------+----------
public | t1 | table | postgres
db_replica=# insert into t1 values (1, 'emp_one');
INSERT 0 1
db_replica=# select * from t1;
sno | emp_id
-----+---------
1 | emp_one
(1 row)
Zdrojový server:
$ /database/pgsql-12.0/bin/psql -p 5732 postgres
psql (12.0)
Type "help" for help.
postgres=# CREATE EXTENSION postgres_fdw;
CREATE EXTENSION
postgres=# CREATE SERVER remote_server
postgres-# FOREIGN DATA WRAPPER postgres_fdw
postgres-# OPTIONS (host '192.168.1.107', port '5432', dbname 'db_replica');
CREATE SERVER
postgres=# CREATE USER MAPPING FOR postgres
postgres-# SERVER remote_server
postgres-# OPTIONS (user 'postgres', password 'admin123');
CREATE USER MAPPING
postgres=# CREATE FOREIGN TABLE remote_t1
postgres-# (sno integer, emp_id text)
postgres-# server remote_server
postgres-# options (schema_name 'public', table_name 't1');
CREATE FOREIGN TABLE
postgres=# select * from remote_t1;
sno | emp_id
-----+---------
1 | emp_one
(1 row)
postgres=# insert into remote_t1 values (2,'emp_two');
INSERT 0 1
postgres=# select * from remote_t1;
sno | emp_id
-----+---------
1 | emp_one
2 | emp_two
(2 rows)
Operace WRITE ze zdrojového serveru okamžitě odráží tabulku vzdáleného serveru. Existuje také podobné rozšíření s názvem oracle_fdw, které umožňuje čtení a zápis mezi tabulkami PostgreSQL a Oracle. Kromě toho existuje další rozšíření s názvem file_fdw, které umožňuje přístup k datům z plochých souborů na disku. Další informace a podrobnosti naleznete v oficiální dokumentaci postgres_fdw zveřejněné zde.
pg_partman
Jak databáze a tabulky rostou, je vždy potřeba zmenšovat databáze, archivovat nepotřebná data nebo alespoň rozdělovat tabulky na různé menší fragmenty. Optimalizátor dotazů proto navštěvuje pouze části tabulky, které splňují podmínky dotazu, místo toho, aby prohledával celou hromadu tabulek.
PostgreSQL již dlouhou dobu nabízí funkce dělení, včetně technik Range, List, Hash a Sub-partitioning. Vyžaduje však mnoho úsilí při správě a správě, jako je definování podřízených tabulek, které zdědí vlastnosti nadřazené tabulky, aby se staly jejími oddíly, vytváření spouštěcích funkcí pro přesměrování dat do oddílu a další vytváření spouštěčů pro volání těchto funkcí atd. kde do hry vstupuje pg_partman, kde se o všechny tyto potíže automaticky postará.
Ukázka
Ukážu rychlou ukázku nastavení a vkládání ukázkových dat. Uvidíte, jak se data vložená do hlavní tabulky automaticky přesměrovávají do oddílů pouhým nastavením pg_partman. Je důležité, aby sloupec klíče oddílu neměl hodnotu null.
db_replica=# show shared_preload_libraries;
shared_preload_libraries
--------------------------
pg_partman_bgw
(1 row)
db_replica=# CREATE SCHEMA partman;
CREATE SCHEMA
db_replica=# CREATE EXTENSION pg_partman SCHEMA partman;
CREATE EXTENSION
db_replica=# CREATE ROLE partman WITH LOGIN;
CREATE ROLE
db_replica=# GRANT ALL ON SCHEMA partman TO partman;
GRANT
db_replica=# GRANT ALL ON ALL TABLES IN SCHEMA partman TO partman;
GRANT
db_replica=# GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA partman TO partman;
GRANT
db_replica=# GRANT EXECUTE ON ALL PROCEDURES IN SCHEMA partman TO partman;
GRANT
db_replica=# GRANT ALL ON SCHEMA PUBLIC TO partman;
GRANT
db_replica=# create table t1 (sno integer, emp_id varchar, date_of_join date not null);
db_replica=# \d
List of relations
Schema | Name | Type | Owner
--------+------+-------+----------
public | t1 | table | postgres
(1 row)
db_replica=# \d t1
Table "public.t1"
Column | Type | Collation | Nullable | Default
--------------+-------------------+-----------+----------+---------
sno | integer | | |
emp_id | character varying | | |
date_of_join | date | | not null |
db_replica=# SELECT partman.create_parent('public.t1', 'date_of_join', 'partman', 'yearly');
create_parent
---------------
t
(1 row)
db_replica=# \d+ t1
Table "public.t1"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
--------------+-------------------+-----------+----------+---------+----------+--------------+-------------
sno | integer | | | | plain | |
emp_id | character varying | | | | extended | |
date_of_join | date | | not null | | plain | |
Triggers:
t1_part_trig BEFORE INSERT ON t1 FOR EACH ROW EXECUTE PROCEDURE t1_part_trig_func()
Child tables: t1_p2015,
t1_p2016,
t1_p2017,
t1_p2018,
t1_p2019,
t1_p2020,
t1_p2021,
t1_p2022,
t1_p2023
db_replica=# select * from t1;
sno | emp_id | date_of_join
-----+--------+--------------
(0 rows)
db_replica=# select * from t1_p2019;
sno | emp_id | date_of_join
-----+--------+--------------
(0 rows)
db_replica=# select * from t1_p2020;
sno | emp_id | date_of_join
-----+--------+--------------
(0 rows)
db_replica=# insert into t1 values (1,'emp_one','01-06-2019');
INSERT 0 0
db_replica=# insert into t1 values (2,'emp_two','01-06-2020');
INSERT 0 0
db_replica=# select * from t1;
sno | emp_id | date_of_join
-----+---------+--------------
1 | emp_one | 2019-01-06
2 | emp_two | 2020-01-06
(2 rows)
db_replica=# select * from t1_p2019;
sno | emp_id | date_of_join
-----+---------+--------------
1 | emp_one | 2019-01-06
(1 row)
db_replica=# select * from t1_p2020;
sno | emp_id | date_of_join
-----+---------+--------------
2 | emp_two | 2020-01-06
(1 row)
Toto je jednoduchá technika rozdělení, ale každý z výše uvedených jednoduchých oddílů lze dále rozdělit na pododdíly. Podívejte se prosím do oficiální dokumentace pg_partman zveřejněné zde, kde najdete další vlastnosti a funkce, které nabízí.
Závěr
Druhá část tohoto blogu se bude zabývat dalšími rozšířeními PostgreSQL, jako jsou pgAudit, pg_repack a HypoPG.