sql >> Databáze >  >> RDS >> PostgreSQL

Moje oblíbená rozšíření PostgreSQL - část druhá

Toto je druhá část mého blogu „Moje oblíbená rozšíření PostgreSQL“, kde jsem vám představil dvě rozšíření PostgreSQL, postgres_fdw a pg_partman. V této části prozkoumám další tři.

pgAudit

Další rozšíření PostgreSQL, které je zajímavé, je za účelem uspokojování požadavků na audit ze strany různých vládních, finančních a jiných certifikačních orgánů, jako je ISO, BSI a FISCAM atd. Standardní protokolovací zařízení, které PostgreSQL nativně nabízí s log_statement =all je užitečné pro monitorování, ale neposkytuje podrobnosti potřebné k vyhovění auditu. Rozšíření pgAudit se zaměřuje na detaily toho, co se stalo pod kapotou, zatímco databáze uspokojovala žádost aplikace.

Prověřovací záznam nebo auditní protokol je vytvořen a aktualizován standardním protokolovacím zařízením poskytovaným PostgreSQL, které poskytuje podrobné protokolování auditu relace a/nebo objektu. Auditní záznam vytvořený programem pgAudit může nabýt obrovských rozměrů v závislosti na nastavení auditu, takže je třeba věnovat pozornost tomu, abyste se předem rozhodli, co a kolik auditování je vyžadováno. Krátká ukázka v následující části ukazuje, jak je pgAudit konfigurován a používán.

Záznam protokolu je vytvořen v protokolu clusteru databáze PostgreSQL, který se nachází v umístění PGDATA/log, ale zprávy protokolu auditu mají předponu „AUDIT:“, aby se rozlišilo mezi běžnými zprávami na pozadí databáze a protokolem auditu evidence.

Ukázka

Oficiální dokumentace pgAudit vysvětluje, že existuje samostatná verze pgAudit pro každou hlavní verzi PostgreSQL, aby byla podporována nová funkce zavedená v každé verzi PostgreSQL. Verze PostgreSQL v tomto demu je 11, takže verze pgAudit bude z větve 1.3.X. Pgaudit.log je základní parametr, který je třeba nastavit a který řídí, jaké třídy příkazů budou protokolovány. Lze jej nastavit pomocí SET pro úroveň relace nebo v souboru postgresql.conf, který má být aplikován globálně.

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>

Položky protokolu, jak je ukázáno ve výše uvedené ukázce, se zapisují do souboru protokolu na pozadí serveru pouze tehdy, když je nastaven parametr log_statement, v tomto případě však není nakonfigurován, ale zprávy auditu jsou zapisovány na základě parametru pgaudit.log, jak je ukázáno v ukázce. K dispozici jsou výkonnější možnosti pro splnění všech vašich požadavků na audit databáze v rámci PostgreSQL, které lze nakonfigurovat podle oficiální dokumentace pgaudit zde nebo na github repository.pg_repack

Toto je oblíbené rozšíření mezi mnoha inženýry PostgreSQL, kteří se přímo podílejí na správě a udržování celkového stavu clusteru PostgreSQL. Důvod pro to bude diskutován o něco později, ale toto rozšíření nabízí funkci pro odstranění nadbytečnosti databáze v databázi PostgreSQL, což je jeden z nepříjemných problémů mezi velmi velkými databázovými clustery PostgreSQL, které vyžadují přeorganizování databáze.

Vzhledem k tomu, že databáze PostgreSQL prochází neustálými a těžkými ZÁPISY (aktualizacemi a mazáním), stará data jsou označena jako smazaná, zatímco se vkládá nová verze řádku, ale stará data nejsou ve skutečnosti vymazána z datový blok. To vyžaduje pravidelnou údržbu zvanou vysávání, což je automatizovaný postup, který se provádí na pozadí a který vymaže všechny řádky „označené jako smazané“. Tento proces je někdy v hovorových termínech nazýván jako sběr odpadu.

Proces vysávání obecně ustupuje operacím databáze během rušnějších časů. Nejméně restriktivní způsob vysávání ve prospěch databázových operací má za následek velké množství „označených jako odstraněných“ řádků, které způsobí, že databáze narůstají nad proporce označované jako „databázové nafouknutí“. Existuje násilný proces vysávání nazvaný VACUUM FULL, ale výsledkem je získání exkluzivního zámku na zpracovávaný databázový objekt, což zastaví databázové operace na tomto objektu.

pg_repack

Právě z tohoto důvodu je pg_repack hitem mezi PostgreSQL DBA a inženýry, protože funguje jako normální proces vysávání, ale nabízí efektivitu VACUUM FULL tím, že nezíská exkluzivní zámek na databázi objekt, zkrátka funguje online. Zde oficiální dokumentace vysvětluje více o dalších metodách reorganizace databáze, ale rychlé demo, jak je uvedeno níže, dá věci do vhodného světla pro lepší pochopení. Existuje požadavek, že cílová tabulka musí mít alespoň jeden sloupec definovaný jako PRIMÁRNÍ KLÍČ, což je obecná norma ve většině nastavení produkční databáze.

Ukázka

Základní demo ukazuje instalaci a použití pg_repack v testovacím prostředí. Toto demo používá verzi 1.4.5 pg_repack, což je nejnovější verze tohoto rozšíření v době publikování tohoto blogu. Demo tabulka t1 má zpočátku 80 000 řádků, které procházejí masivní operací mazání, která smaže každý 5. řádek tabulky. Spuštění pg_repack ukazuje velikost tabulky před a za.

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

Funkce delete5 odstraní 200 000 řádků z tabulky t1 pomocí počítadla, které zvýší 5 počtů

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)

Jak je uvedeno výše, původní velikost tabulky se po provedení funkce delete5 nezmění, což ukazuje, že řádky v tabulce stále existují. Provedení pg_repack vymaže ty „označené jako odstraněné“ řádky z tabulky t1, čímž se velikost tabulky t1 zmenší na 57 MB. Další dobrá věc na pg_repack je volba pro suchý běh s příznakem -N, pomocí kterého můžete zkontrolovat, co se bude během skutečného běhu provádět.

HypoPG

Další zajímavé rozšíření je totožné s populárním konceptem nazývaným neviditelné indexy mezi proprietárními databázovými servery. Rozšíření HypoPG umožňuje DBA vidět účinek zavedení hypotetického indexu (který neexistuje) a zda to zlepší výkon jednoho nebo více dotazů, a proto název HypoPG.

Vytvoření hypotetického indexu nevyžaduje žádné prostředky CPU ani disku, spotřebovává však soukromou paměť připojení. Vzhledem k tomu, že hypotetický index není uložen v žádných tabulkách databázového katalogu, nedochází k žádnému vlivu nadýmání tabulky. Z tohoto důvodu nelze v příkazu EXPLAIN ANALYZE použít hypotetický index, zatímco prostý EXPLAIN je dobrým způsobem, jak posoudit, zda bude potenciální index použit daný problematickým dotazem. Zde je rychlé demo, které vysvětluje, jak HypoPG funguje.

Ukázka

Vytvořím tabulku obsahující 100 000 řádků pomocí generovat_series a provedu několik jednoduchých dotazů, abych ukázal rozdíl v odhadech nákladů s hypotetickými indexy a bez nich.

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)

Výše uvedený příklad ukazuje, jak lze snížit odhadované celkové náklady z 1791 na 8,06 přidáním indexu do pole „id“ v tabulce pro optimalizaci jednoduchého dotazu. To také dokazuje, že index se ve skutečnosti nepoužívá, když je dotaz prováděn pomocí EXPLAIN ANALYZE, která provádí dotaz v reálném čase. Existuje také způsob, jak přibližně zjistit, kolik místa na disku index zabírá, pomocí funkce hypopg_list_indexes rozšíření.

HypoPG má několik dalších funkcí pro správu hypotetických indexů a kromě toho také nabízí způsob, jak zjistit, zda rozdělení tabulky zlepší výkon dotazů načítajících velký soubor dat. Rozšíření HypoPG nabízí hypotetickou možnost rozdělení a další z nich lze následovat odkazem na oficiální dokumentaci.

Závěr

Jak je uvedeno v první části, PostgreSQL se v průběhu let vyvíjel tak, že se stal jen větším, lepším a rychlejším s rychlým vývojem jak v nativním zdrojovém kódu, tak i v rozšířeních plug and play. Open source verze nového PostgreSQL může být nejvhodnější pro mnoho IT obchodů, které provozují jeden z hlavních proprietárních databázových serverů, aby se snížily jejich IT CAPEX a OPEX.

Existuje spousta rozšíření PostgreSQL, která nabízejí funkce od monitorování po vysokou dostupnost a od škálování po ukládání binárních datových souborů do formátu čitelného člověkem. Doufáme, že výše uvedené ukázky vrhly obrovské světlo na maximální potenciál a sílu databáze PostgreSQL.


  1. Co je MySQL:Přehled

  2. Nesoulad datových typů (kód 20) při vkládání

  3. Porovnejte dvě databáze MySQL

  4. MariaDB JSON_ARRAYAGG() Vysvětleno