Ceci fait suite à mon article de blog précédent dans lequel j'avais abordé le sujet des extensions PostgreSQL . Les extensions PostgreSQL sont un ensemble d'améliorations plug and play qui ajoutent un ensemble de fonctionnalités supplémentaires à un cluster PostgreSQL. Certaines de ces fonctionnalités sont aussi simples que la lecture ou l'écriture dans une base de données externe, tandis que d'autres peuvent constituer une solution sophistiquée pour mettre en œuvre la réplication, la surveillance, etc. de la base de données.
PostgreSQL a évolué au fil des ans, passant d'un simple ORDBMS open source à un puissant système de base de données avec plus de 30 ans de développement actif offrant fiabilité, performances et toutes les fonctionnalités conformes à ACID. Avec PostgreSQL 12 sorti il y a quelques mois, ce logiciel de base de données ne fait que s'agrandir, s'améliorer et s'accélérer.
Parfois, des extensions devaient être ajoutées à un cluster PostgreSQL pour obtenir des fonctionnalités améliorées qui n'étaient pas disponibles dans le code natif, car elles n'étaient pas développées en raison de contraintes de temps ou en raison de preuves insuffisantes de la base de données de cas extrêmes problèmes. Je vais discuter de quelques-unes de mes extensions préférées sans ordre particulier, avec quelques démos utilisées par les développeurs et les DBA.
Certaines de ces extensions peuvent nécessiter d'être incluses dans le paramètre serveur shared_preload_libraries sous la forme d'une liste séparée par des virgules à précharger au démarrage du serveur. Bien que la plupart des extensions soient incluses dans le module contrib du code source, certaines doivent être téléchargées à partir d'un site Web externe dédié uniquement aux extensions PostgreSQL appelé PostgreSQL Extension Network.
Dans cette série de blogs en deux parties, nous aborderons les extensions utilisées pour accéder aux données (postgres_fwd) et réduire ou archiver les bases de données (pg_partman). Des extensions supplémentaires seront abordées dans la deuxième partie.
postgres_fdw
Le postgres_fdw est une extension de wrapper de données étrangères qui peut être utilisée pour accéder aux données stockées dans des serveurs PostgreSQL externes. Cette extension est similaire à une ancienne extension appelée dblink mais elle diffère de son prédécesseur en offrant une syntaxe conforme aux normes et de meilleures performances.
Les composants importants de postgres_fdw sont un serveur, un mappage utilisateur et une table étrangère. Une surcharge mineure s'ajoute au coût réel d'exécution des requêtes sur des serveurs distants, à savoir la surcharge de communication. L'extension postgres_fdw est également capable de communiquer avec un serveur distant ayant une version allant jusqu'à PostgreSQL 8.3, étant ainsi rétrocompatible avec les versions antérieures.
Démo
La démo présentera une connexion de PostgreSQL 12 à une base de données PostgreSQL 11. Les paramètres de pg_hba.conf ont déjà été configurés pour que les serveurs se parlent. Les fichiers de contrôle des extensions doivent être chargés dans le répertoire d'accueil partagé de PostgreSQL avant de créer l'extension à partir de l'intérieur d'un cluster PostgreSQL.
Serveur distant :
$ /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)
Serveur source :
$ /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)
L'opération WRITE du serveur source reflète immédiatement la table du serveur distant. Une extension similaire appelée oracle_fdw existe également qui permet l'accès en LECTURE et en ÉCRITURE entre les tables PostgreSQL et Oracle. En plus de cela, il existe une autre extension appelée file_fdw qui permet l'accès aux données à partir de fichiers plats sur le disque. Veuillez vous référer à la documentation officielle de postgres_fdw publiée ici, pour plus d'informations et de détails.
pg_partman
À mesure que les bases de données et les tables se développent, il est toujours nécessaire de réduire les bases de données, d'archiver les données qui ne sont pas nécessaires ou au moins de partitionner les tables en divers fragments plus petits. Ainsi, l'optimiseur de requête ne visite que les parties de la table qui satisfont aux conditions de la requête, au lieu d'analyser l'ensemble du tas de tables.
PostgreSQL propose depuis longtemps des fonctionnalités de partitionnement, notamment des techniques de plage, de liste, de hachage et de sous-partitionnement. Cependant, cela nécessite de nombreux efforts d'administration et de gestion, tels que la définition de tables enfants qui héritent des propriétés d'une table parent pour en faire ses partitions, la création de fonctions de déclenchement pour rediriger les données vers une partition et la création de déclencheurs pour appeler ces fonctions, etc. où pg_partman entre en jeu, où tous ces tracas sont pris en charge automatiquement.
Démo
Je vais montrer une démonstration rapide de la configuration et de l'insertion d'exemples de données. Vous verrez comment les données insérées dans la table principale sont automatiquement redirigées vers les partitions en configurant simplement pg_partman. Il est important que la colonne de clé de partition ne soit pas nulle.
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)
Il s'agit d'une technique de partitionnement simple, mais chacune des partitions simples ci-dessus peut être divisée en sous-partitions. Veuillez consulter la documentation officielle de pg_partman publiée ici, pour plus de fonctionnalités et de fonctions qu'il offre.
Conclusion
La deuxième partie de ce blog discutera d'autres extensions PostgreSQL comme pgAudit, pg_repack et HypoPG.