sql >> Database >  >> RDS >> PostgreSQL

Mijn favoriete PostgreSQL-extensies - deel twee

Dit is het tweede deel van mijn blog 'Mijn favoriete PostgreSQL-extensies' waarin ik je kennis heb laten maken met twee PostgreSQL-extensies, postgres_fdw en pg_partman. In dit deel zal ik er nog drie onderzoeken.

pgAudit

De volgende interessante PostgreSQL-extensie is bedoeld om te voldoen aan de auditvereisten van verschillende overheids-, financiële en andere certificerende instanties zoals ISO, BSI en FISCAM, enz. De standaard logfunctie die PostgreSQL native aanbiedt with log_statement =all is handig voor monitoring, maar het geeft niet de details die nodig zijn om te voldoen aan de audit of om het hoofd te bieden aan de audit. De pgAudit-extensie richt zich op de details van wat er onder de motorkap gebeurde, terwijl een database aan een applicatieverzoek voldeed.

Een audittrail of auditlog wordt gemaakt en bijgewerkt door een standaard logfunctie van PostgreSQL, die gedetailleerde sessie- en/of object-auditlogging biedt. Het auditspoor dat door pgAudit wordt gecreëerd, kan enorm groot worden, afhankelijk van de audit-instellingen, dus moet zorgvuldig worden beslist over wat en hoeveel auditing vooraf vereist is. Een korte demo in de volgende sectie laat zien hoe pgAudit wordt geconfigureerd en in gebruik wordt genomen.

Het logboekspoor wordt gemaakt in het PostgreSQL-databaseclusterlogboek dat is gevonden op de PGDATA/log-locatie, maar de auditlogboekberichten worden voorafgegaan door een "AUDIT:" label om onderscheid te maken tussen reguliere database-achtergrondberichten en auditlogboek verslagen.

Demo

De officiële documentatie van pgAudit legt uit dat er een aparte versie van pgAudit bestaat voor elke hoofdversie van PostgreSQL om nieuwe functionaliteit te ondersteunen die in elke PostgreSQL-release wordt geïntroduceerd. De versie van PostgreSQL in deze demo is 11, dus de versie van pgAudit komt uit de 1.3.X-tak. De pgaudit.log is de fundamentele parameter die moet worden ingesteld die bepaalt welke klassen van instructies worden gelogd. Het kan worden ingesteld met een SET voor een sessieniveau of binnen het postgresql.conf-bestand om globaal te worden toegepast.

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>

De logboekvermeldingen, zoals weergegeven in de demo hierboven, worden alleen naar het achtergrondlogboekbestand van de server geschreven wanneer de parameter log_statement is ingesteld, maar in dit geval is het niet geconfigureerd, maar worden de auditberichten geschreven op grond van van de parameter pgaudit.log zoals blijkt uit de demo. Er zijn krachtigere opties beschikbaar om te voldoen aan al uw database-auditvereisten binnen PostgreSQL, die kunnen worden geconfigureerd door de officiële documentatie van pgaudit hier of op de github repository.pg_repack

te volgen.

Dit is een favoriete extensie van veel PostgreSQL-engineers die direct betrokken zijn bij het beheren en onderhouden van de algemene gezondheid van een PostgreSQL-cluster. De reden daarvoor zal iets later worden besproken, maar deze extensie biedt de functionaliteit om een ​​opgeblazen database binnen een PostgreSQL-database te verwijderen, wat een van de grootste zorgen is onder zeer grote PostgreSQL-databaseclusters die een herschikking van de database vereisen.

Omdat een PostgreSQL-database constant en zwaar SCHRIJFT (updates en verwijderingen), worden de oude gegevens gemarkeerd als verwijderd terwijl de nieuwe versie van de rij wordt ingevoegd, maar de oude gegevens worden niet echt van een gegevensblok. Dit vereist een periodieke onderhoudshandeling, stofzuigen genaamd, een geautomatiseerde procedure die op de achtergrond wordt uitgevoerd en alle "gemarkeerde als verwijderde" rijen wist. Dit proces wordt in de omgangstaal soms ook wel garbage collection genoemd.

Het stofzuigproces maakt over het algemeen plaats voor de databasebewerkingen tijdens drukkere tijden. De minst beperkende manier van stofzuigen ten gunste van databasebewerkingen resulteert in een groot aantal "gemarkeerd als verwijderd" rijen waardoor databases buiten proportie groeien, wat wordt aangeduid als "databaseopgeblazen gevoel". Er is een krachtig stofzuigproces genaamd VACUUM FULL, maar dat resulteert in het verkrijgen van een exclusieve vergrendeling op het database-object dat wordt verwerkt, waardoor database-bewerkingen op dat object worden stopgezet.

pg_repack

Het is om deze reden dat pg_repack een hit is onder PostgreSQL DBA's en ingenieurs, omdat het het werk doet van een normaal stofzuigproces, maar een efficiëntie van VACUUM FULL biedt door geen exclusieve vergrendeling op een database te verwerven object, kortom, het werkt online. De officiële documentatie hier legt meer uit over de andere methoden voor het reorganiseren van een database, maar een korte demo zoals hieronder zal de zaken in het juiste licht plaatsen voor een beter begrip. Er is een vereiste dat de doeltabel ten minste één kolom moet hebben die is gedefinieerd als PRIMAIRE SLEUTEL, wat een algemene norm is in de meeste productiedatabaseconfiguraties.

Demo

De basisdemo toont de installatie en het gebruik van pg_repack in een testomgeving. Deze demo gebruikt versie 1.4.5 van pg_repack, de nieuwste versie van deze extensie op het moment van publicatie van deze blog. Een demotabel t1 heeft aanvankelijk 80000 rijen die een massale verwijderingshandeling ondergaan, waarbij elke 5e rij van de tabel wordt verwijderd. Een uitvoering van pg_repack toont de grootte van de tabel ervoor en erna.

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

De delete5-functie verwijdert 200000 rijen uit de t1-tabel met behulp van een teller die 5 tellingen verhoogt

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)

Zoals hierboven weergegeven, verandert de oorspronkelijke grootte van de tabel niet na het uitvoeren van de functie delete5 , wat aangeeft dat de rijen nog steeds in de tabel bestaan. De uitvoering van pg_repack wist die 'gemarkeerd als verwijderd' rijen uit de t1-tabel, waardoor de grootte van de t1-tabel wordt teruggebracht tot 57 MB. Een ander voordeel van pg_repack is een optie voor dry run met -N flag, waarmee je kunt controleren wat er tijdens een echte run wordt uitgevoerd.

HypoPG

De volgende interessante extensie is identiek aan een populair concept genaamd onzichtbare indexen onder eigen databaseservers. Met de HypoPG-extensie kan een DBA het effect zien van het introduceren van een hypothetische index (die niet bestaat) en of deze de prestaties van een of meer zoekopdrachten zal verbeteren, en vandaar de naam HypoPG.

Het maken van een hypothetische index vereist geen CPU- of schijfbronnen, maar het verbruikt wel het privégeheugen van een verbinding. Aangezien de hypothetische index niet is opgeslagen in databasecatalogustabellen, is er geen invloed van een opgeblazen tabel. Het is om deze reden dat een hypothetische index niet kan worden gebruikt in een EXPLAIN ANALYZE-instructie, terwijl een gewone EXPLAIN een goede manier is om te beoordelen of een potentiële index zal worden gebruikt door een bepaalde problematische query. Hier is een korte demo om uit te leggen hoe HypoPG werkt.

Demo

Ik ga een tabel maken met 100000 rijen met behulp van generation_series en een paar eenvoudige query's uitvoeren om het verschil in kostenramingen met en zonder hypothetische indexen te laten zien.

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)

De bovenstaande tentoonstelling laat zien hoe de geschatte totale kosten kunnen worden verlaagd van 1791 naar 8,06 door een index toe te voegen aan het 'id'-veld van de tabel om een ​​eenvoudige zoekopdracht te optimaliseren. Het bewijst ook dat de index niet echt wordt gebruikt wanneer de query wordt uitgevoerd met een EXPLAIN ANALYZE die de query in realtime uitvoert. Er is ook een manier om erachter te komen hoeveel schijfruimte de index ongeveer inneemt met behulp van de functie hypopg_list_indexes van de extensie.

De HypoPG heeft een paar andere functies om hypothetische indexen te beheren en daarnaast biedt het ook een manier om erachter te komen of het partitioneren van een tabel de prestaties verbetert van query's die een grote dataset ophalen. Er is een hypothetische partitioneringsoptie van de HypoPG-extensie en meer hiervan kan worden gevolgd door te verwijzen naar de officiële documentatie.

Conclusie

Zoals vermeld in deel één, is PostgreSQL in de loop der jaren geëvolueerd en is het alleen maar groter, beter en sneller geworden met snelle ontwikkeling, zowel in de oorspronkelijke broncode als in plug-and-play-extensies. Een open source-versie van de nieuwe PostgreSQL kan het meest geschikt zijn voor tal van IT-winkels die een van de belangrijkste eigen databaseservers gebruiken, om hun IT-CAPEX en OPEX te verminderen.

Er zijn tal van PostgreSQL-extensies die functies bieden variërend van monitoring tot hoge beschikbaarheid en van schalen tot het dumpen van binaire gegevensbestanden in een voor mensen leesbaar formaat. Het is te hopen dat de bovenstaande demonstraties een enorm licht hebben geworpen op het maximale potentieel en de kracht van een PostgreSQL-database.


  1. Patchbeleid

  2. Hoe MariaDB op CentOS 8 te installeren

  3. MySQL datumnotatie spiekbriefje

  4. Flask-SQLAlchemy Index met kleine letters - functioneel overslaan, niet ondersteund door SQLAlchemy-reflectie