PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Mes extensions PostgreSQL préférées - Deuxième partie

Ceci est la deuxième partie de mon blog "Mes extensions PostgreSQL préférées" dans laquelle je vous ai présenté deux extensions PostgreSQL, postgres_fdw et pg_partman. Dans cette partie, j'en explorerai trois autres.

pgAudit

La prochaine extension PostgreSQL d'intérêt a pour but de satisfaire aux exigences d'audit de divers organismes gouvernementaux, financiers et autres organismes de certification tels que ISO, BSI et FISCAM, etc. La fonction de journalisation standard que PostgreSQL offre nativement with log_statement =all est utile pour la surveillance, mais il ne fournit pas les détails requis pour se conformer ou faire face à l'audit. L'extension pgAudit se concentre sur les détails de ce qui s'est passé sous le capot, alors qu'une base de données satisfaisait une demande d'application.

Une piste d'audit ou un journal d'audit est créé et mis à jour par une fonction de journalisation standard fournie par PostgreSQL, qui fournit une journalisation d'audit de session et/ou d'objet détaillée. La piste d'audit créée par pgAudit peut atteindre une taille énorme en fonction des paramètres d'audit, il faut donc veiller à décider au préalable quoi et combien d'audit est nécessaire. Une brève démonstration dans la section suivante montre comment pgAudit est configuré et utilisé.

La trace du journal est créée dans le journal du cluster de base de données PostgreSQL qui se trouve à l'emplacement PGDATA/log, mais les messages du journal d'audit sont précédés d'une étiquette « AUDIT : » pour faire la distinction entre les messages d'arrière-plan de la base de données et le journal d'audit. enregistrements.

Démo

La documentation officielle de pgAudit explique qu'il existe une version distincte de pgAudit pour chaque version majeure de PostgreSQL afin de prendre en charge les nouvelles fonctionnalités introduites dans chaque version de PostgreSQL. La version de PostgreSQL dans cette démo est 11, donc la version de pgAudit proviendra de la branche 1.3.X. Le pgaudit.log est le paramètre fondamental à définir qui contrôle les classes d'instructions qui seront enregistrées. Il peut être défini avec un SET pour un niveau de session ou dans le fichier postgresql.conf pour être appliqué globalement.

postgres=# set pgaudit.log = 'read, write, role, ddl, misc';

SET



cat $PGDATA/pgaudit.log

pgaudit.log = 'read, write, role, ddl, misc'



db_replica=# show pgaudit.log;

         pgaudit.log

------------------------------

 read, write, role, ddl, misc

(1 row)



2020-01-29 22:51:49.289 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,3,1,MISC,SHOW,,,show pgaudit.log;,<not logged>



db_replica=# create table t1 (f1 integer, f2 varchar);

CREATE TABLE



2020-01-29 22:52:08.327 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,4,1,DDL,CREATE TABLE,,,"create table t1 (f1 integer, f2 varchar);",<not logged>



db_replica=#  insert into t1 values (1,'one');

INSERT 0 1

db_replica=#  insert into t1 values (2,'two');

INSERT 0 1

db_replica=#  insert into t1 values (3,'three');

INSERT 0 1

2020-01-29 22:52:19.261 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,5,1,WRITE,INSERT,,,"insert into t1 values (1,'one');",<not logged>

20-01-29 22:52:38.145 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,6,1,WRITE,INSERT,,,"insert into t1 values (2,'two');",<not logged>

2020-01-29 22:52:44.988 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,7,1,WRITE,INSERT,,,"insert into t1 values (3,'three');",<not logged>



db_replica=# select * from t1 where f1 >= 2;

 f1 |  f2

----+-------

  2 | two

  3 | three

(2 rows)



2020-01-29 22:53:09.161 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,9,1,READ,SELECT,,,select * from t1 where f1 >= 2;,<not logged>



db_replica=# grant select on t1 to usr_replica;

GRANT



2020-01-29 22:54:25.283 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,13,1,ROLE,GRANT,,,grant select on t1 to usr_replica;,<not logged>



db_replica=# alter table t1 add f3 date;

ALTER TABLE



2020-01-29 22:55:17.440 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,23,1,DDL,ALTER TABLE,,,alter table t1 add f3 date;,<not logged>



db_replica=# checkpoint;

CHECKPOINT



2020-01-29 22:55:50.349 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,33,1,MISC,CHECKPOINT,,,checkpoint;,<not logged>



db_replica=# vacuum t1;

VACUUM



2020-01-29 22:56:03.007 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,34,1,MISC,VACUUM,,,vacuum t1;,<not logged>



db_replica=# show log_statement;

 log_statement

---------------

 none



2020-01-29 22:56:14.740 AEDT 4710 db_replica postgres [local] psql LOG:  AUDIT: SESSION,36,1,MISC,SHOW,,,show log_statement;,<not logged>

Les entrées de journal, comme indiqué dans la démo ci-dessus, ne sont écrites dans le fichier journal d'arrière-plan du serveur que lorsque le paramètre log_statement est défini, mais dans ce cas, il n'est pas configuré mais les messages d'audit sont écrits en vertu du paramètre pgaudit.log comme en témoigne la démo. Il existe des options plus puissantes disponibles pour répondre à toutes vos exigences d'audit de base de données dans PostgreSQL, qui peuvent être configurées en suivant la documentation officielle de pgaudit ici ou sur le github repository.pg_repack

Il s'agit d'une extension préférée parmi de nombreux ingénieurs PostgreSQL qui sont directement impliqués dans la gestion et le maintien de la santé générale d'un cluster PostgreSQL. La raison en sera discutée un peu plus tard, mais cette extension offre la fonctionnalité de supprimer le gonflement de la base de données dans une base de données PostgreSQL, ce qui est l'un des problèmes les plus récurrents parmi les très grands clusters de bases de données PostgreSQL nécessitant une réorganisation de la base de données.

Comme une base de données PostgreSQL subit des WRITES constants et lourds (mises à jour et suppressions), les anciennes données sont marquées comme supprimées tandis que la nouvelle version de la ligne est insérée, mais les anciennes données ne sont pas réellement effacées d'un bloc de données. Cela nécessite une opération de maintenance périodique appelée aspirateur, qui est une procédure automatisée qui s'exécute en arrière-plan et efface toutes les lignes "marquées comme supprimées". Ce processus est parfois appelé ramasse-miettes en termes familiers.

Le processus de nettoyage cède généralement la place aux opérations de la base de données pendant les périodes les plus occupées. La manière la moins restrictive de passer l'aspirateur en faveur des opérations de base de données entraîne un grand nombre de lignes "marquées comme supprimées", provoquant une croissance hors de proportion des bases de données appelée "gonflement de la base de données". Il existe un processus de nettoyage puissant appelé VACUUM FULL, mais cela entraîne l'acquisition d'un verrou exclusif sur l'objet de base de données en cours de traitement, ce qui bloque les opérations de base de données sur cet objet.

pg_repack

C'est pour cette raison que pg_repack est un succès parmi les administrateurs de base de données et les ingénieurs PostgreSQL, car il fait le travail d'un processus de vidage normal mais offre une efficacité de VACUUM FULL en n'acquérant pas de verrou exclusif sur une base de données objet, bref, ça marche en ligne. La documentation officielle ici explique plus en détail les autres méthodes de réorganisation d'une base de données, mais une démonstration rapide comme ci-dessous mettra les choses en lumière pour une meilleure compréhension. Il est nécessaire que la table cible ait au moins une colonne définie comme CLÉ PRIMAIRE, ce qui est une norme générale dans la plupart des configurations de base de données de production.

Démo

La démo de base montre l'installation et l'utilisation de pg_repack dans un environnement de test. Cette démo utilise la version 1.4.5 de pg_repack qui est la dernière version de cette extension au moment de la publication de ce blog. Une table de démonstration t1 a initialement 80000 lignes qui subissent une opération massive de suppression, qui supprime toutes les 5e lignes de la table. Une exécution de pg_repack montre la taille de la table avant et après.

mydb=# CREATE EXTENSION pg_repack;

CREATE EXTENSION



mydb=# create table t1 (no integer primary key, f_name VARCHAR(20), l_name VARCHAR(20), d_o_b date);

CREATE TABLE

mydb=# insert into t1 (select generate_series(1,1000000,1),'a'||

mydb(# generate_series(1,1000000,1),'a'||generate_series(1000000,1,-1),

mydb(# cast( now() - '1 year'::interval * random()  as date ));

INSERT 0 1000000



mydb=# SELECT pg_size_pretty( pg_total_relation_size('t1'));

 pg_size_pretty

----------------

 71 MB

(1 row)



mydb=# CREATE or replace FUNCTION delete5() RETURNS void AS $$

mydb$# declare

mydb$# counter integer := 0;

mydb$# BEGIN

mydb$#

mydb$#  while counter <= 1000000

mydb$# loop

mydb$# delete from t1 where no=counter;

mydb$# counter := counter + 5;

mydb$# END LOOP;

mydb$# END;

mydb$# $$ LANGUAGE plpgsql;

CREATE FUNCTION

La fonction delete5 supprime 200 000 lignes de la table t1 à l'aide d'un compteur qui incrémente de 5 unités

mydb=# select delete5();

 delete5

------



(1 row)

mydb=# SELECT pg_size_pretty( pg_total_relation_size('t1'));

 pg_size_pretty

----------------

 71 MB

(1 row)



$ pg_repack -t t1 -N -n -d mydb -p 5433

INFO: Dry run enabled, not executing repack

INFO: repacking table "public.t1"



$ pg_repack -t t1 -n -d mydb -p 5433

INFO: repacking table "public.t1"



mydb=# SELECT pg_size_pretty( pg_total_relation_size('t1'));

 pg_size_pretty

----------------

 57 MB

(1 row)

Comme indiqué ci-dessus, la taille d'origine du tableau ne change pas après l'exécution de la fonction delete5 , ce qui indique que les lignes existent toujours dans le tableau. L'exécution de pg_repack efface les lignes "marquées comme supprimées" de la table t1, ramenant la taille de la table t1 à 57 Mo. Une autre bonne chose à propos de pg_repack est une option de simulation avec l'indicateur -N, à l'aide de laquelle vous pouvez vérifier ce qui sera exécuté lors d'une exécution réelle.

HypoPG

La prochaine extension intéressante est identique à un concept populaire appelé index invisibles parmi les serveurs de bases de données propriétaires. L'extension HypoPG permet à un DBA de voir l'effet de l'introduction d'un index hypothétique (qui n'existe pas) et s'il améliorera les performances d'une ou plusieurs requêtes, d'où le nom HypoPG.

La création d'un index hypothétique ne nécessite aucune ressource CPU ou disque, mais elle consomme la mémoire privée d'une connexion. Comme l'index hypothétique n'est stocké dans aucune table de catalogue de base de données, il n'y a donc pas d'impact de gonflement de table. C'est pour cette raison qu'un index hypothétique ne peut pas être utilisé dans une instruction EXPLAIN ANALYZE alors qu'un EXPLAIN simple est un bon moyen d'évaluer si un index potentiel sera utilisé par une requête problématique donnée. Voici une démo rapide pour expliquer comment fonctionne HypoPG.

Démo

Je vais créer une table contenant 100 000 lignes à l'aide de generate_series et exécuter quelques requêtes simples pour montrer la différence entre les estimations de coûts avec et sans index hypothétiques.

olap=# CREATE EXTENSION hypopg;

CREATE EXTENSION



olap=# CREATE TABLE stock (id integer, line text);

CREATE TABLE



olap=# INSERT INTO stock SELECT i, 'line ' || i FROM generate_series(1, 100000) i;

INSERT 0 100000



olap=# ANALYZE STOCK;

ANALYZE



olap=#  EXPLAIN SELECT line FROM stock WHERE id = 1;

                       QUERY PLAN

---------------------------------------------------------

 Seq Scan on stock  (cost=0.00..1791.00 rows=1 width=10)

   Filter: (id = 1)

(2 rows)

olap=# SELECT * FROM hypopg_create_index('CREATE INDEX ON stock (id)') ;

 indexrelid |       indexname

------------+-----------------------

      25398 | <25398>btree_stock_id

(1 row)



olap=# EXPLAIN SELECT line FROM stock WHERE id = 1;

                                     QUERY PLAN

------------------------------------------------------------------------------------

 Index Scan using <25398>btree_stock_id on stock  (cost=0.04..8.06 rows=1 width=10)

   Index Cond: (id = 1)

(2 rows)



olap=# EXPLAIN ANALYZE SELECT line FROM stock WHERE id = 1;

                                             QUERY PLAN

----------------------------------------------------------------------------------------------------

 Seq Scan on stock  (cost=0.00..1791.00 rows=1 width=10) (actual time=0.028..41.877 rows=1 loops=1)

   Filter: (id = 1)

   Rows Removed by Filter: 99999

 Planning time: 0.057 ms

 Execution time: 41.902 ms

(5 rows)



olap=# SELECT indexname, pg_size_pretty(hypopg_relation_size(indexrelid))

olap-#   FROM hypopg_list_indexes() ;

       indexname       | pg_size_pretty

-----------------------+----------------

 <25398>btree_stock_id | 2544 kB

(1 row)



olap=# SELECT pg_size_pretty(pg_relation_size('stock'));

 pg_size_pretty

----------------

 4328 kB

(1 row)

L'exposition ci-dessus montre comment le coût total estimé peut être réduit de 1791 à 8,06 en ajoutant un index au champ "id" de la table pour optimiser une requête simple. Cela prouve aussi que l'index n'est pas vraiment utilisé lorsque la requête est exécutée avec un EXPLAIN ANALYZE qui exécute la requête en temps réel. Il existe également un moyen de connaître approximativement l'espace disque occupé par l'index à l'aide de la fonction hypopg_list_indexes de l'extension.

L'HypoPG a quelques autres fonctions pour gérer les index hypothétiques et en plus de cela, il offre également un moyen de savoir si le partitionnement d'une table améliorera les performances des requêtes récupérant un grand ensemble de données. Il existe une option de partitionnement hypothétique de l'extension HypoPG et d'autres peuvent être suivies en se référant à la documentation officielle.

Conclusion

Comme indiqué dans la première partie, PostgreSQL a évolué au fil des ans en devenant plus grand, meilleur et plus rapide avec un développement rapide à la fois dans le code source natif et dans les extensions plug and play. Une version open source du nouveau PostgreSQL peut être la plus appropriée pour de nombreuses boutiques informatiques qui exécutent l'un des principaux serveurs de base de données propriétaires, afin de réduire leurs CAPEX et OPEX informatiques.

Il existe de nombreuses extensions PostgreSQL qui offrent des fonctionnalités allant de la surveillance à la haute disponibilité et de la mise à l'échelle au vidage des fichiers de données binaires dans un format lisible par l'homme. Nous espérons que les démonstrations ci-dessus ont mis en lumière le potentiel et la puissance maximum d'une base de données PostgreSQL.