PostgreSQL 8.3
Pavel Stěhule
Department of Mapping and Cartography, Faculty of Civil Engineering
Czech Technical University in Prague
stehule kix.fsv.cvut.cz
Kĺıčová slova: Database systems, Open Source
Abstrakt
Práce na Open Source databáźıch pokračuj́ı nezadržitelným tempem. Vývojáři se muśı vy-
rovnat s rostoućımi požadavky uživatel̊u na objem dat ukládaných do databáźı, na náročněǰśı
požadavky na odezvu atd. Zat́ım nedostǐznou metou je implementace celého standardu ANSI
SQL 200x. Všechny databáze z velké trojky (Firebird, MySQL a PostgreSQL) použ́ıvaj́ı mul-
tigeneračńı architekturu, cenově orientované hledáńı optimálńıho prováděćıho plánu, write
ahead log atd. MySQL se profiluje jako SQL databáze schopná použ́ıvat specializované da-
tabázové backendy schopné maximálńı efektivity pro určité konkrétńı prostřed́ı. PostgreSQL
je široce použitelná databáze, těž́ıćı z vynikaj́ıćı stability, s perfektńı rozšiřitelnost́ı a kom-
fortńım prostřed́ım. Konečně Firebird je vynikaj́ıćı embeded databáze, která se osvědčuje v
tiśıćıch instalaćıch na desktopech.
Podle p̊uvodńıho plánu mělo doj́ıt k uvolněńı verze 8.3 koncem léta – mělo j́ıt o verzi obsahuj́ıćı
patche dokončené pro 8.2, ale v té době nedostatečně otestované. Nakonec se ukázalo, že ty
nejd̊uležitěǰśı patche je třeba dopracovat. Jednalo se o tak atraktivńı vlastnosti, že se rozhodlo
s vydáńım nové verze počkat. 8.3 obsahuje integrovaný fulltext, podporu opožděného potvr-
zováńı (asynchronńı commit), synchronizované sekvenčńı čteńı datových soubor̊u, úsporněǰśı
ukládáńı dynamických datových typ̊u (kraťśıch 256byte), HOT updates a sofistikovaněǰśı aktu-
alizaci index̊u (hot indexes). Z patch̊u připravených pro 8.2 se v 8.3 neobjev́ı podpora bitma-
pových index̊u a podpora aktualizovatelných pohled̊u. P̊uvodńı řešeńı založené na pravidlech
(rules) bylo př́ılǐs komplikované. 8.3 obsahuje podporu aktualizovatelných kurzor̊u, a je docela
dobře možné, že aktualizovatelné pohledy budou ve verzi 8.4 implementovány právě s pomoćı
této tř́ıdy kurzor̊u.
Vývoj pokračuje implementaćı daľśıch modul̊u SQL. Ve verzi 8.3 je to konkrétně SQL/XML
(rozš́ıřeńı ANSI SQL), která umožňuje operace s XML dokumenty př́ımo v databázi a zjed-
nodušuje generováńı XML dokument̊u. Zásadńı (interńı) změnou je zkráceńı hlavičky řádku z
28 bajt̊u na 24 bajt̊u. Daľśı změnou, která by měla vést k minimalizaci velikosti uložených dat
je diverzifikace typu varlena. Tento typ se v PostgreSQL použ́ıvá pro serializaci hodnot všech
typ̊u s variabilńı délkou. Trochu připomı́ná string v Pascalu. Prvńı byty nesou informaci o
délce, daľśı nesou obsah. Starš́ı verze PostgreSQL znaly jen typ varlena s 4byte informaćı o
Geinformatics FCE CTU 2007 91
PostgreSQL 8.3
délce. 8.3 podporuje také typ varlena s 1byte záhlav́ım. Úspora by se měla projevit hlavně u
typu NUMERIC a krátkých řetězc̊u. K překladu PostgreSQL lze poč́ınaje touto verźı použ́ıt
jak gcc, MINGW tak Microsoft Visual C++ (na platformě Microsoft Windows).
Integrace TSearch2
Integrace TSearch2 do jádra PostgreSQL je výsledkem dlouholetého úsiĺı Olega Bartunova a
Teodora Sigaeva. Dı́ky integraci se zjednoduš́ı konfigurace fulltextu a pro určité jazyky (pro
které existuje podpora v projektu Snowball) lze fulltext použ́ıvat hned po instalaci databáze.
Čeština bohužel mezi tyto jazyky nepatř́ı – je potřeba provést několik daľśıch operaćı. Předně
převést Open Office slovńıky do kódováńı UTF8 a zkoṕırovat je do př́ıslušného podadresáře
PostgreSQL. Dále zaregistrovat slovńık a provést tzv. konfiguraci. Kromě konfigurace jsou
rozd́ıly mezi integrovaným fulltextem a TSearch2 (z verze 8.2) sṕı̌se kosmetické.
CREATE TEXT SEARCH DICTIONARY cspell1(
template=ispell,
dictfile = czech, afffile=czech, stopwords=czech);
CREATE TEXT SEARCH CONFIGURATION cs (copy=english);
ALTER TEXT SEARCH CONFIGURATION cs
ALTER MAPPING FOR word, lword WITH cspell, simple;
postgres=# select * from ts_debug(’cs’,’Přı́liš žlut’oučký kůň se napil žluté vody’);
Alias | Description | Token | Dictionaries | Lexized token
-------+---------------+-----------+-----------------+---------------------
word | Word | Přı́liš | {cspell,simple} | cspell: {přı́liš}
blank | Space symbols | | {} |
word | Word | žlut’oučký | {cspell,simple} | cspell: {žlut’oučký}
blank | Space symbols | | {} |
word | Word | kůň | {cspell,simple} | cspell: {kůň}
blank | Space symbols | | {} |
lword | Latin word | se | {cspell,simple} | cspell: {}
blank | Space symbols | | {} |
lword | Latin word | napil | {cspell,simple} | cspell: {napı́t}
blank | Space symbols | | {} |
word | Word | žluté | {cspell,simple} | cspell: {žlutý}
blank | Space symbols | | {} |
lword | Latin word | vody | {cspell,simple} | cspell: {voda}
(13 rows)
Podporu fulltextu nad konkrétńım sloupcem můžeme aktivovat např. vytvořeńım funkcionál-
ńıho GIN indexu.
CREATE INDEX data_poznamka_ftx ON data
USING gin(to_tsvector(’cs’, poznamka))
a vyhledávat operátorem @@ (fulltextové vyhledáváńı)
SELECT * FROM data
WHERE to_tsvector(’cs’,poznamka) @@ to_tsquery(’žlutá & voda’)
Podpora SQL/XML
Zásadně se změnila podpora XML. To co v předchoźıch verźıch se neohrabaně řešilo přes
doplňky se nyńı dostalo př́ımo do jádra. Jednak jsou k dispozici funkce generuj́ıćı XML
(xmlelement, xmlforest, ...) jednak jsou tu funkce mapuj́ıćı obsah tabulky do XML. Výsledkem
může být XML schéma (použitelné pro validaci nebo pro přenos definice tabulky), XML
dokument s integrovaným schématem, nebo samotný XML dokument. Jelikož je výstupńı
Geinformatics FCE CTU 2007 92
PostgreSQL 8.3
formát standardizován v SQL/XML, neměl by být přenos těchto tabulek problémem (mezi
těmi databázemi, které SQL/XML podporuj́ı).
pavel=# create table a(a date, b varchar(10));
CREATE TABLE
pavel=# insert into a values(current_date, ’něco’),(current_date+1, NULL);
INSERT 0 2
pavel=# select table_to_xml_and_xmlschema(’a’, true, false, ’’);
table_to_xml_and_xmlschema
------------------------------------------------------------------------------------------------
2007-02-19
něco
2007-02-20
Stejného výsledku dosáhneme pomoćı funkćı generuj́ıćıch XML. Jejich použit́ı je univerzálněǰśı,
a o trochu komplikovaněǰśı:
pavel=# SELECT xmlelement(name a,
xmlagg(
xmlelement(name row,
xmlforest(a,b))))
FROM a;
xmlelement
----------------------------------------------------------------------------
2007-02-19něco
2007-02-20
(1 řádka)
V PostgreSQL stále chyb́ı COLLATE. Podařilo se alespoň rozš́ı̌rit klauzuli ORDER a to
Geinformatics FCE CTU 2007 93
PostgreSQL 8.3
v pozicováńı řádk̊u s hodnotou NULL (ORDER BY .. NULLS FIRST/LAST). Adekvátně
tomu se rozš́ı̌rili parametry u btree index̊u. Refaktorizaćı kódu se doćılila podpora NULL v
indexech. Starš́ı verze nedokázaly indexovat hodnotu NULL.
postgres=# explain SELECT count(*) FROM fx WHERE a IS NULL;
QUERY PLAN
-------------------------------------------------------------------
Aggregate (cost=8.28..8.29 rows=1 width=0)
-> Index Scan using bb on fx (cost=0.00..8.28 rows=1 width=0)
Index Cond: (a IS NULL)
(3 rows)
Nové datové typy a rozš́ı̌reńı možnost́ı stávaj́ıćıch datových typ̊u
Ve verzi 8.2 PostgreSQL podporuje několik nových datových typ̊u: XML zajǐst’uj́ıćı validitu
obsahu, UUID (universal unique identifier) dle RFC 4122. Vlastńı generátor je v contribu
uuid-ossp (je potřeba doinstalovat package uuid a uuid-devel). K dispozici je deset r̊uzných
zp̊usob̊u generováńı jednoznačných univerzálńıch identifikátor̊u. Dále je tu možnost použ́ıvat
vlastńı výčtové typy (zjevně inspirováno MySQL). Na rozd́ıl od MySQL v PostgreSQL je
nutné před použit́ım vytvořit pro určitý seznam hodnot vlastńı typ. Jeho použit́ı je ovšem
podstatně širš́ı než v MySQL.
-- klasické řešenı́ výčtu
CREATE TABLE foo(varianta char(2) CHECK (varianta IN (’a1’,’a2’,’a3’)));
-- pouziti typu enum
CREATE TYPE vycet_variant AS ENUM(’a1’,’a2’,’a3’,’a4’,’a5’);
CREATE TABLE foo(varianta vycet_variant);
-- enum lze pouzit i v poli
SELECT ’{a1,a3}’::vycet_variant[] as pripustne_varianty;
Rozsah hodnot źıskáme voláńım funkce enum range. Pokud funkci předáme parametr NULL,
źıskáme úplný výčet hodnot.
postgres=# SELECT enum_range(’a2’::va, ’a4’::vycet_variant);
enum_range
------------
{a2,a3,a4}
(1 row)
postgres=# SELECT enum_range(null::vycet_variant);
enum_range
------------------
{a1,a2,a3,a4,a5}
(1 row)
Kromě opravy několika chyb v PL/pgSQL (chyběla kontrola NOT NULL domén), došlo již k
ńıže zmı́něnému rozš́ı̌reńı př́ıkazu RETURN o tabulkový výraz, a konečně lze i v PL/pgSQL
použ́ıvat scrollable kurzory. Ty PostgreSQL podporuje deľśı dobu, z PL/pgSQL je však nebylo
možné použ́ıvat. Kromě scrollable kurzor̊u lze v PL/pgSQL (ale i vně) použ́ıvat updatable
kurzory podle ANSI SQL 92 (oproti ANSI SQL 2003 př́ısněǰśı omezeńı). U SRF funkćı můžeme
upřesnit jejich náročnost a předpoklad počtu vrácených řádk̊u (atributy COST a ROWS). V
předchoźıch verźıch se při hledáńı optimálńıho prováděćıho plánu předpokládalo, že SRF
funkce vrát́ı vždy 1000 řádk̊u, což nebyla pokaždé být pravda (výsledkem byl neoptimálńı
prováděćı plán).
Vedleǰśım efektem implementace subsystému pro kešováńı prováděćıch plán̊u bylo odstraněńı
problémů s neplatnými prováděćımi plány v PL/pgSQL. Tyto problémy se projevovaly hlavně
při použit́ı dočasných tabulek, které se nesměly odstraňovat. Jinak docházelo, při použit́ı SQL
Geinformatics FCE CTU 2007 94
PostgreSQL 8.3
př́ıkazu vázaného na zrušenou a opětovně vytvořenou tabulku, k chybě. Nyńı se cache čist́ı
v závislosti na rušeńı databázových objekt̊u. Samozřejmě, že funkce volané v cyklu budou
prováděny efektivně jen tehdy, pokud nebude docházet k regenerováńı prováděćıch plán̊u.
V 8.3 můžeme pole vytvářet i ze složených typ̊u – v podstatě můžeme uložit tabulku jako
jednu hodnotu). Stále však chyb́ı podpora domén (a vkládaný záznam je nutné explicitně
typovat):
postgres=# CREATE TYPE at AS (a integer, b integer);
CREATE TYPE
postgres=# CREATE TABLE foo(a at[]);
CREATE TABLE
postgres=# INSERT INTO foo VALUES(ARRAY[(10,20)::at]);
INSERT 0 1
postgres=# INSERT INTO foo VALUES(ARRAY[(10,20)::at, (20,30)::at]);
INSERT 0 1
postgres=# SELECT * FROM foo;
a
-----------------------
{"(10,20)"}
{"(10,20)","(20,30)"}
(2 rows)
postgres=# SELECT a[1] FROM foo;
a
---------
(10,20)
(10,20)
(2 rows)
postgres=# SELECT a[1].a FROM foo;
a
----
10
10
(2 rows)
Optimalizace
Ve verzi 8.3 došlo k celé řada změn a úprav, které by měly vést k rychleǰśımu zpracováńı SQL
př́ıkaz̊u. Zrychlit by mělo nač́ıtáńı dat př́ıkazem COPY. U tohoto př́ıkazu neńı žádný d̊uvod,
proč by mělo docházet k zápisu do write ahead logu (ten je základem procesu obnovy po
pádu PostgreSQL) a tato verze dokáže u tohoto př́ıkazu obcházet zápis so WAL (COPY muśı
být v transakci). Nově PostgreSQL efektivněji provád́ı dotazy s ORDER BY c LIMIT n, kdy
znatelně zrychĺı výběr prvńıch n řádk̊u řazených podle sloupce c, pokud nad sloupcem c neńı
index (nedocháźı k seřazeńı celé tabulky). Př́ıkaz EXPLAIN ANALYZE nyńı poskytuje daľśı
informace o řazeńı (typ, spotřeba paměti):
t=# explain analyze SELECT * FROM foo ORDER BY a LIMIT 12;
QUERY PLAN
----------------------------------------------------------------------------------------------
Limit (cost=3685.48..3685.51 rows=12 width=4) (actual time=290.549..290.588 rows=12 loops=1)
-> Sort (cost=3685.48..3935.48 rows=100000 width=4) (actual time=290.544..290.557 rows=12
loops=1)
Sort Key: a
Sort Method: top-N heapsort Memory: 17kB
-> Seq Scan on foo (cost=0.00..1393.00 rows=100000 width=4) (actual
time=0.036..153.526 rows=100000 loops=1)
Total runtime: 290.658 ms
(6 rows)
t=# explain analyze SELECT * from foo order by a;
Geinformatics FCE CTU 2007 95
PostgreSQL 8.3
QUERY PLAN
---------------------------------------------------------------------------------------------
Sort (cost=10894.82..11144.82 rows=100000 width=4) (actual time=520.528..683.190
rows=100000 loops=1)
Sort Key: a
Sort Method: external merge Disk: 1552kB
-> Seq Scan on foo (cost=0.00..1393.00 rows=100000 width=4) (actual time=0.022..159.028
rows=100000 loops=1)
Total runtime: 800.065 ms
(5 rows)
V předchoźıch verźıch neexistovala hash funkce pro typ NUMERIC. Proto se pro spojováńı
tabulek skrz sloupce typu NUMERIC nedala použ́ıt metoda HASHJOIN, která patř́ı k nej-
rychleǰśım.
Zrychlit by měla i operace LIKE, zvlášt’ když se použije v́ıce bajtové kódováńı – použil se jiný
algoritmus na porovnáńı řetězc̊u. Nyńı se již neporovnávaj́ı znaky, ale bajty, což ušetř́ı jednu
konverzi z UTF8 do UTF16. Na zkušebńı tabulce o sta tiśıćıch žlutých końıch sekvenčńı čteńı
tabulky se zrychlilo z 169ms na 105ms.
Pokud se zjist́ı, že docháźı k souběžnému sekvenčńımu čteńı jedné tabulky z v́ıce obslužných
proces̊u, tak se systém pokuśı tyto procesy sesynchronizovat (pokud dojde k sekvenčńımu
čteńı, tak se ve velké většině př́ıpad̊u čte celý datový soubor). Sekvenčńı čteńı všech proces̊u
je přibližně stejně rychlé, a tak je šance, že všechny procesy budou cht́ıt v jednu chv́ıli stejnou
datovou stránku, a je mnohem vyšš́ı pravděpodobnost, že ji najdou ve vyrovnávaćı paměti.
Pokud nedocháźı k synchronizaci procesu, tak pravděpodobnost, že požadovaná stránka je
ve vyrovnávaćı paměti je mnohem menš́ı, č́ımž se zvyšuje pravděpodobnost požadavku na
fyzické čteńı datové stránky se souboru. Tato optimalizace má smysl při větš́ım počtu současně
pracuj́ıćıch uživatel̊u, kdy je vyšš́ı pravděpodobnost, že dojde k synchronizaci, a také kdy je
větš́ı tlak na vyrovnávaćı pamět’.
Podpora asynchronńıho commitu je méně nebezpečnou obdobou nedoporučované konfigurace
fsync=off. Při asynchronńım commitu je zaručena konzistence databáze, nicméně při havárii
hroźı riziko ztráty několika posledńıch transakćı. Parametr synchronous commit je vázán na
session, takže vývojář může na základě své úvahy zvolit méně bezpečný, nicméně rychleǰśı
zp̊usob řešeńı transakćı. Testy ukazuj́ı, že má smysl uvažovat o tomto parametru v př́ıpadě
málo zat́ıžené databáze, kdy nedocháźı ke sd́ıleńı zápisu do transakčńıho logu – typicky při
administraci databáze, kdy ostatńı uživatelé nemaj́ı př́ıstup k databázi a s databáźı pracuje
pouze DBA.
8.3 obsahuje sofistikovaněǰśı metodu pro vytvářeńı nových verźı označovanou jako HOT (Heap
Only Tuples). Starš́ı verze při jakékoliv operaci UPDATE modifikovaly relevantńı indexy, a to
i přesto, že nedošlo k modifikaci oindexovaných sloupc̊u. Tzv. horký UPDATE je podmı́něný
dostatkem volného prostoru na datové stránce a změnou pouze neoindexovaných sloupc̊u. Po-
kud tyto podmı́nky nejsou splněny, provede se klasický ”studený” UPDATE. HOT UPDATE
je v̊uči klasické implementaci operace mnohem úsporněǰśı a tud́ıž i rychleǰśı. Nav́ıc tato nová
metoda dokáže využ́ıt prostor na datové stránce obsazený nedostupnými verzemi (které byly
vytvořeny také touto metodou) bez potřeby spuštěńı operace VACUUM.
Geinformatics FCE CTU 2007 96
PostgreSQL 8.3
Spuštěńı operace VACUUM ve v́ıce procesech
V 8.3 je automatické vacuováńı implementováno s podporou v́ıce proces̊u, tj. pokud trvá
vacuum jedné databáze př́ılǐs dlouho, vytvoř́ı se nový pracovńı proces (worker), který zajǐst’uje
vacuováńı daľśıch databáźı (smyslem neńı urychlit d́ıky paralelizaci operaci VACUUM, ale
zajistit, že v daném časovém okně se provede spravedlivě VACUUM všech databáźı). Úkolem
pracovńıho procesu je projet provozńı statistiky všech tabulek v databázi a vybrat tabulky
určené k vacuováńı. Pracovńı proces je na úrovni databáze sekvenčńı, paralelizace je na úrovni
clusteru. Nově vacuum také zajǐst’uje samočinné voláńı VACUUM FREEZE coby ochrany před
přetečeńım rozsahu identifikátor̊u verźı řádk̊u.
Rozš́ı̌reńı PL/pgSQL – RETURN QUERY, lokálńı systémové proměnné
Předchoźı verze neumožňovaly vrátit množinu záznamů jako výsledek SRF funkce. Jediným
řešeńım bylo voláńı př́ıkazu RETURN NEXT pro každý řádek výsledku dotazu. V podstatě
totéž (ale na nižš́ı úrovni, tud́ıž efektivněji) provád́ı př́ıkaz RETURN QUERY. Jeho para-
metrem je SQL dotaz, jehož výsledek se připoj́ı k výstupu. Podobně jako RETURN NEXT
neukončuje prováděńı funkce.
CREATE OR REPLACE FUNCTION dirty_series(m integer, n integer)
RETURNS SETOF integer AS $$
BEGIN
RETURN QUERY SELECT * FROM generate_series(1,m) g(i)
WHERE i % n = 0;
RETURN;
END; $$ LANGUAGE plpgsq;
Daľśı novou vlastnost́ı je možnost modifikovat systémové proměnné lokálně pro určitou funkci.
Podobně se chová T-SQL nebo MySQL, kde se ukládá aktuálńı nastaveńı systémových promě-
nných v čase registrace funkce. V PostgreSQL žádný podobný mechanismus nebyl. Tato
vlastnost řeš́ı zabezpečeńı SECURITY DEFINER funkćı, kterým bylo možné podvrhnout
útočńık̊uv kód změnou systémové proměnné search path. Zápis je zřejmý z následuj́ıćıho
př́ıkladu:
CREATE FUNCTION report_guc(text) RETURNS TEXT AS
$$ SELECT current_setting($1) $$ LANGUAGE sql
SET regex_flavor = basic;
ALTER FUNCTION report_guc(text)
RESET search_path
SET regex_flavor = extended;
Podpora režimu Warm Standby, prototyp replikace založené na transakčńım
logu
PostgreSQL 8.3 umožňuje nakonfigurovat a použ́ıvat dva PostgreSQL servery tak, že prvńı
slouž́ı jako výkonný server a druhý jako záložńı, kdy změny v datech na prvńım serveru jsou
na druhý server replikovány exportem transakčńıho logu. Tato konfigurace se použ́ıvá pouze
v náročných aplikaćı, kde časté klasické zálohováńı z d̊uvodu objemu neńı možné a kde ztráta
dat neńı akceptovatelná – kde zákazńık vyžaduje pr̊uběžné zálohováńı. Nejde o multi-master
replikaci jako v př́ıpadě MySQL. Druhý systém je až do signálu nedostupný, tud́ıž t́ımto
zp̊usobem replikace nelze rozložit zátěž serveru. Pro usnadněńı konfigurace verze 8.3 obsahuje
př́ıkaz pg standby (ve stejnojmenném contrib adresáři), který zajist́ı udržeńı druhé instance
PostgreSQL v režimu Warm Standby.
Geinformatics FCE CTU 2007 97
PostgreSQL 8.3
Master (postgresql.conf):
archive_command = ’cp %p ../archive/%f’
archive_timeout = 20
Warm Standby (recovery.conf)
restore_command = ’pg_standby -l -d -k 255 -r 2 -s 2 -w 0 -t /tmp/stop /usr/local/pgsql/archive %f %p \
2>> standby.log’
Po modifikaci konfiguračńıch soubor̊u stač́ı spustit oba servery. Záložńı server z̊ustane v re-
covery režimu, kdy pg standby postupně podvrhuje segmenty transakčńıho logu (sleduje ex-
portované segmenty) a nedovoĺı dokončit obnovu záložńı databáze. Teprve po signalizaci,
pg standby (existenćı předem určeného souboru (v př́ıkladu /tmp/stop)) oznámı́ serveru, že
se jednalo o posledńı segment transakčńıho logu a dovoĺı dokončeńı obnovy a t́ım i přepnut́ı
do stavu, kdy záložńı server je schopen přij́ımat požadavky. Signálńı soubor muśı vygenerovat
uživatel postgres, tak aby jej pg standby mohlo odstranit. Pokud tento soubor nelze odstra-
nit, replikace zhavaruje. V praxi toto řešeńı neńı př́ılǐs použitelné, nebot’ pg standby nedokáže
zachytit výjimku a tud́ıž ji ani nedokáže korektně obsloužit (aniž by nebyl nevratně přerušen
proces replikace spojený se ztrátou dat na záložńım serveru).
4916 ? S 0:00 /usr/local/pgsql/bin/postmaster -D /usr/local/pgsql2/data
4918 ? Ss 0:00 postgres: startup process
5226 ? S 0:00 sh -c pg_standby -l -d -t
/tmp/aaa /usr/local/pgsql/archive 000000010000000000000018 pg_xlog/RECOVERYXLOG 2>> standby.log
5227 ? S 0:00 pg_standby -l -d -t
/tmp/aaa /usr/local/pgsql/archive 000000010000000000000018 pg_xlog/RECOVERYXLOG
Záložńı cluster muśı být klonem zálohovaného clusteru. Muśı být vytvořen zkoṕırováńım
adresáře databázového clusteru – nevytvář́ı se př́ıkazem initdb.
Regulárńı výrazy
Podpora reg. výraz̊u neńı v PostgreSQL novinkou. V 8.3 se objevily nové funkce regexp match-
es a dvojice regexp split to array a regexp split to table. Pro řadu úloh nyńı nemuśıme pou-
ž́ıvat plperl. V následuj́ıćım př́ıkladu je z XML dokumentu separován seznam identifikačńıch
č́ısel, který je následně indexován a použit k vyhledáváńı. Ke stejnému účelu by bylo možné
použ́ıt i funkce podporuj́ıćı XPath výrazy. Toto řešeńı je řádově rychleǰśı než intuitivńı (a
velice pomalé) řešeńı s LIKE.
objednava_v_xml LIKE ’%hledane_id%’
Pole NEW.objednavka id produktu je aktualizované v triggeru:
NEW.objednavka_id_produktu := ARRAY(SELECT i[1] FROM
regexp_matches(NEW.objednavka_v_xml,’(\\d+)’,’g’ r(i));
Funkčně srovnatelný predikát výše uvedenému LIKE je:
objednavka_id_produktu @> ARRAY[hledane_id]
Ostatńı změny
Nezanedbatelného rozš́ı̌reńı se dočkalo prostřed́ı ecpg. Vylepšuje podporu prepared state-
ments, nab́ıźı auto prepare mód, pozicované proměnné. Jedná o zásadńı změny – došlo
ke změně verze z 4.4 na 6.0. Jednou z prvńıch backport̊u z EnterpriseDB je debugger a
profiler PL/pgSQL. Nová verze pgAdminIII obsahuje grafické rozhrańı debuggeru, které je
zpř́ıstupněno, pokud je v PostgreSQL nainstalován plugin s debuggerem (ke stažeńı na pg-
foundry). Ve srovnáńı s moderńımi debuggery obsahuje PL/pgSQL pouze základńı funkce.
Geinformatics FCE CTU 2007 98
PostgreSQL 8.3
pavel=# LOAD ’$libdir/plugins/plugin_profiler’;
LOAD
pavel=# SET plpgsql.profiler_tablename = ’profilerstats’;
SET
pavel=# SELECT line_number, sourcecode, time_total, exec_count, func_oid::regproc
FROM profilerstats
ORDER BY 1;
line_number | sourcecode | time_total | exec_count | func_oid
-------------+-----------------------+------------+------------+----------
0 | | 0 | 0 | x
1 | begin | 0 | 0 | x
2 | for i in 1..4 loop | 0.000315 | 1 | x
3 | return next i; | 9.8e-05 | 4 | x
4 | end loop; | 0 | 0 | x
5 | return; | 3e-06 | 1 | x
(6 rows)
Index advisor
Index advisor je plugin plánovače dotaz̊u. Jedná se o prototyp navržený Tomem Lanem za
účelem demonstrace monitorovaćıho rozhrańı návrhu a optimalizace prováděćıch plán̊u. Pokud
se aktivuje, tak optimalizátor bere v úvahu, kromě existuj́ıćıch index̊u, hypotetické indexy
vytvořené nad každým sloupcem:
regression=# load ’/home/tgl/pgsql/advisor’;
LOAD
regression=# explain select * from fooey order by unique2,unique1;
QUERY PLAN
----------------------------------------------------------------------------------------
Sort (cost=809.39..834.39 rows=10000 width=8)
Sort Key: unique2, unique1
-> Seq Scan on fooey (cost=0.00..145.00 rows=10000 width=8)
Plan with hypothetical indexes:
Index Scan using on fooey (cost=0.00..376.00 rows=10000 width=8)
(6 rows)
regression=# explain select * from fooey where unique2 in (1,2,3);
QUERY PLAN
------------------------------------------------------------------------------------
Seq Scan on fooey (cost=0.00..182.50 rows=3 width=8)
Filter: (unique2 = ANY (’{1,2,3}’::integer[]))
Plan with hypothetical indexes:
Bitmap Heap Scan on fooey (cost=12.78..22.49 rows=3 width=8)
Recheck Cond: (unique2 = ANY (’{1,2,3}’::integer[]))
-> Bitmap Index Scan on (cost=0.00..12.77 rows=3 width=0)
Index Cond: (unique2 = ANY (’{1,2,3}’::integer[]))
(8 rows)
Vývoj v následuj́ıćıch letech
Největš́ı slabinou PostgreSQL je chyběj́ıćı podpora replikaci. V této oblasti nikoliv neza-
slouženě dominuj́ı komerčńı systémy. Dále PostgreSQL nemá dořešenou internacionalizaci,
tzv. COLLATES, které nab́ıźı jak MySQL, tak Firebird. Konečně třet́ı oblast́ı, kterou je nyńı
třeba intenzivně se zabývat je podpora OLAP databáźı. Nelze předpokládat, že by Postgre-
SQL v brzké době podporoval OLAP databáze, nicméně existuj́ı určité indicie, že hlavńım
tématem následuj́ıćı verze (8.4) bude podpora analytických a rekurzivńıch dotaz̊u. V deľśım
Geinformatics FCE CTU 2007 99
PostgreSQL 8.3
časovém horizontu je možné očekávat zařazeńı podpory zpracováńı tzv. proudových dat, je-
likož platforma PostgreSQL byla použita k vytvořeńı experimentálńıch prototyp̊u proudových
databáźı a kromě toho, část týmu vývojář̊u se touto problematikou aktivně zabývá.
Odkazy
1. Přehled vlastnost́ı jednotlivých verźı1
2. Přehled plánovaných rozš́ı̌reńı v př́ı̌st́ı verzi2
1
http://developer.postgresql.org/index.php/Feature Matrix
2
http://developer.postgresql.org/index.php/Todo:WishlistFor84
Geinformatics FCE CTU 2007 100
http://developer.postgresql.org/index.php/Feature_Matrix
http://developer.postgresql.org/index.php/Todo:WishlistFor84