sql >> Database teknologi >  >> RDS >> PostgreSQL

Mine foretrukne PostgreSQL-udvidelser - Anden del

Dette er anden del af min blog "Mine foretrukne PostgreSQL-udvidelser", hvor jeg havde introduceret dig til to PostgreSQL-udvidelser, postgres_fdw og pg_partman. I denne del vil jeg udforske tre mere.

pgAudit

Den næste PostgreSQL-udvidelse af interesse er med det formål at opfylde revisionskrav fra forskellige offentlige, finansielle og andre certificeringsorganer såsom ISO, BSI og FISCAM osv. Standardlogningsfaciliteten, som PostgreSQL tilbyder indbygget med log_statement =alt er nyttigt til overvågning, men det giver ikke de detaljer, der kræves for at overholde eller stå over for revisionen. pgAudit-udvidelsen fokuserer på detaljerne om, hvad der skete under emhætten, mens en database imødekom en ansøgningsanmodning.

Et revisionsspor eller revisionslog oprettes og opdateres af en standardlogningsfacilitet leveret af PostgreSQL, som giver detaljeret sessions- og/eller objektrevisionslogning. Revisionssporet, der er oprettet af pgAudit, kan blive enormt i størrelse afhængigt af revisionsindstillinger, så man skal være opmærksom på at beslutte, hvad og hvor meget revision der kræves på forhånd. En kort demo i det følgende afsnit viser, hvordan pgAudit er konfigureret og taget i brug.

Logsporet oprettes i PostgreSQL-databaseklyngeloggen, der findes på PGDATA/log-placeringen, men revisionslogmeddelelserne er præfikset med en "AUDIT:"-label for at skelne mellem almindelige databasebaggrundsmeddelelser og revisionslog. optegnelser.

Demo

Den officielle dokumentation af pgAudit forklarer, at der findes en separat version af pgAudit for hver større version af PostgreSQL for at understøtte ny funktionalitet introduceret i hver PostgreSQL-udgivelse. Versionen af ​​PostgreSQL i denne demo er 11, så versionen af ​​pgAudit vil være fra 1.3.X-grenen. Pgaudit.log er den grundlæggende parameter, der skal indstilles, og som styrer, hvilke klasser af udsagn, der bliver logget. Det kan indstilles med et SET for et sessionsniveau eller i postgresql.conf-filen, der skal anvendes globalt.

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>

Logposterne, som vist i demoen ovenfor, skrives kun til serverbaggrundslogfilen, når parameteren log_statement er indstillet, men i dette tilfælde er den ikke konfigureret, men revisionsmeddelelserne er skrevet i kraft af pgaudit.log-parameteren som vist i demoen. Der er mere effektive muligheder tilgængelige for at opfylde alle dine databaserevisionskrav i PostgreSQL, som kan konfigureres ved at følge den officielle dokumentation for pgaudit her eller på github repository.pg_repack

Dette er en yndet udvidelse blandt mange PostgreSQL-ingeniører, der er direkte involveret i styring og vedligeholdelse af den generelle sundhed i en PostgreSQL-klynge. Årsagen til det vil blive diskuteret lidt senere, men denne udvidelse tilbyder funktionaliteten til at fjerne database-bloat i en PostgreSQL-database, hvilket er en af ​​de nagende bekymringer blandt meget store PostgreSQL-databaseklynger, der kræver databaseomlægning.

Da en PostgreSQL-database gennemgår konstante og tunge WRITES (opdateringer og sletninger), markeres de gamle data som slettede, mens den nye version af rækken indsættes, men de gamle data slettes faktisk ikke fra en datablok. Dette kræver en periodisk vedligeholdelsesoperation kaldet støvsugning, som er en automatiseret procedure, der udføres i baggrunden, og som rydder alle "markerede som slettede" rækker. Denne proces omtales undertiden som affaldsindsamling i daglig tale.

Støvsugningsprocessen giver generelt plads til databaseoperationerne i travle tider. Den mindst restriktive måde at støvsuge på til fordel for databaseoperationer resulterer i et stort antal "markerede som slettede" rækker, der får databaser til at vokse ud af proportioner, kaldet "database bloat". Der er en kraftfuld støvsugningsproces kaldet VACUUM FULL, men det resulterer i, at der opnås en eksklusiv lås på databaseobjektet, der behandles, og stopper databasehandlinger på det objekt.

pg_repack

Det er af denne grund, at pg_repack er et hit blandt PostgreSQL DBA'er og ingeniører, fordi det udfører arbejdet med en normal støvsugeproces, men tilbyder en effektivitet på VACUUM FULL ved ikke at anskaffe en eksklusiv lås på en database objekt, kort sagt, det virker online. Den officielle dokumentation her forklarer mere om de andre metoder til at omorganisere en database, men en hurtig demo som nedenfor vil sætte tingene i passende lys for bedre forståelse. Der er et krav om, at måltabellen skal have mindst én kolonne defineret som en PRIMÆR NØGLE, hvilket er en generel norm i de fleste produktionsdatabaseopsætninger.

Demo

Den grundlæggende demo viser installationen og brugen af ​​pg_repack i et testmiljø. Denne demo bruger version 1.4.5 af pg_repack, som er den seneste version af denne udvidelse på tidspunktet for udgivelsen af ​​denne blog. En demo tabel t1 har i starten 80.000 rækker, som gennemgår en massiv operation med sletning, som sletter hver 5. række i tabellen. En udførelse af pg_repack viser størrelsen af ​​tabellen før og efter.

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

Slet5-funktionen sletter 200.000 rækker fra t1-tabellen ved hjælp af en tæller, der øger 5 tællinger

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)

Som vist ovenfor ændres den oprindelige størrelse af tabellen ikke efter udførelse af delete5-funktionen, som viser, at rækkerne stadig eksisterer i tabellen. Udførelsen af ​​pg_repack rydder de 'markerede som slettede' rækker fra t1-tabellen, hvilket reducerer størrelsen af ​​t1-tabellen til 57 MB. En anden god ting ved pg_repack er en mulighed for tørløb med -N flag, hvor du kan kontrollere, hvad der vil blive udført under en faktisk kørsel.

HypoPG

Den næste interessante udvidelse er identisk med et populært koncept kaldet usynlige indekser blandt proprietære databaseservere. HypoPG-udvidelsen gør det muligt for en DBA at se effekten af ​​at indføre et hypotetisk indeks (som ikke eksisterer), og om det vil forbedre ydeevnen af ​​en eller flere forespørgsler, og deraf navnet HypoPG.

Oprettelsen af ​​et hypotetisk indeks kræver ingen CPU- eller diskressourcer, men det bruger en forbindelses private hukommelse. Da det hypotetiske indeks ikke er gemt i nogen databasekatalogtabeller, er der ingen indvirkning af table bloat. Det er af denne grund, at et hypotetisk indeks ikke kan bruges i en EXPLAIN ANALYZE-sætning, mens en almindelig EXPLAIN er en god måde at vurdere, om et potentielt indeks vil blive brugt af en given problematisk forespørgsel. Her er en hurtig demo, der forklarer, hvordan HypoPG virker.

Demo

Jeg vil oprette en tabel indeholdende 100.000 rækker ved hjælp af gener_series og udføre et par simple forespørgsler for at vise forskellen i omkostningsestimater med og uden hypotetiske indekser.

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)

Ovenstående udstilling viser, hvordan de anslåede samlede omkostninger kan reduceres fra 1791 til 8,06 ved at tilføje et indeks til "id"-feltet i tabellen for at optimere en simpel forespørgsel. Det beviser også, at indekset ikke rigtig bruges, når forespørgslen udføres med en EXPLAIN ANALYSE, som udfører forespørgslen i realtid. Der er også en måde at finde ud af omtrent hvor meget diskplads indekset optager ved at bruge funktionen hypopg_list_indexes i udvidelsen.

HypoPG'en har et par andre funktioner til at styre hypotetiske indekser, og derudover tilbyder den også en måde at finde ud af, om partitionering af en tabel vil forbedre ydeevnen af ​​forespørgsler, der henter et stort datasæt. Der er en hypotetisk opdelingsmulighed for HypoPG-udvidelsen, og mere af den kan følges ved at henvise til den officielle dokumentation.

Konklusion

Som anført i første del, har PostgreSQL udviklet sig gennem årene i kun at blive større, bedre og hurtigere med hurtig udvikling både i den oprindelige kildekode såvel som plug and play-udvidelser. En open source-version af den nye PostgreSQL kan være mest velegnet til mange it-butikker, der kører en af ​​de store proprietære databaseservere, for at reducere deres IT CAPEX og OPEX.

Der er masser af PostgreSQL-udvidelser, der tilbyder funktioner lige fra overvågning til høj tilgængelighed og fra skalering til dumping af binære datafiler i et menneskeligt læsbart format. Det er håbet, at ovenstående demonstrationer har kastet enormt lys over det maksimale potentiale og kraften i en PostgreSQL-database.


  1. MySQL CAST – Sådan skriver du Cast i MySQL

  2. Sådan omdefineres de kolonner, der returneres af en lagret procedure i SQL Server

  3. Indsæt DML med bindingsvariabel:BRUGER Klausul af Udfør øjeblikkelig erklæring

  4. ORA-01830:billede i datoformat slutter før konvertering af hele inputstrengen / Vælg sum hvor datoforespørgsel