Přečteno, potvrdil jsem si názor že dělat DB je těžký (včetně správného používání).
Co mě zaujalo je použití mesonu. Vlastně je to poprvé co jsem na něj narazil mimo GNOME a mám z toho radost, že se prosazuje.
Dík za články!
Postgres potřeboval něco, co by šlo použít napříč všemi podporovanými systémy - a kombinace meson, ninja je rozumná volba. Letos se kvůli Postgresu portoval meson na AIX.
Pro mne, co by autora extenzí, je konfigurace buildu, relativně nezajímavá, pokud jsou hotové skripty. Pro meson bohužel hotové nebyly, takže jsem je musel napsat. Měl jsem problém s tím, že pár kroků, které bych s make udělal triviálně v mesonu nejde udělat. Meson není složitý, a je k němu relativně dobrá dokumentace. V dokumentaci mi ale chyběla kapitola nebo FAQ typu "meson pro uživatele configure/make". Nenašel jsem dokumentaci, dokument, který by odpovídal na moje otázky.
Přijde mi, že je to dost analogické se systemd (nezpochybňuji výhody systemd vůči init skriptům). U startup skriptů nebo u make se stačilo naučit pár principů a relativně jednoduchý univerzální jazyk, a člověk mohl začít něco dělat. U systemd nebo mesonu je potřeba se toho naučit na začátku mnohem víc a je mnohem víc potřeba znát a dodržovat určité konvence. V obou případech jsem ale nenašel tutorial, který by mi sedl (a dnes dohledat něco kvalitního na netu, pokud člověk není expertem na danou oblast) skoro nejde.
Ad „Co mě zaujalo je použití mesonu. Vlastně je to poprvé co jsem na něj narazil mimo GNOME a mám z toho radost, že se prosazuje.“
Když se na to podívám z perspektivy toho, že stavím systém od základů (bootstrappable build), tak to nevnímám zrovna pozitivně, protože to přidává závislost na Pythonu – a to i v případě, že chci sestavit aplikaci, která si vystačí s C nebo C++ kompilátorem tzn. typicky GCC nebo LLVM/CLang, v některých případech by dokonce stačil minimalistický kompilátor typu TinyCC.
Když se na to podívám z perspektivy toho, že stavím systém od základů (bootstrappable build), tak to nevnímám zrovna pozitivně, protože to přidává závislost na Pythonu – a to i v případě, že chci sestavit aplikaci, která si vystačí s C nebo C++ kompilátorem tzn. typicky GCC nebo LLVM/CLang, v některých případech by dokonce stačil minimalistický kompilátor typu TinyCC.
No ono je to někdy ještě mnohem horší. Kdyby to byl jen python, tak ok. Jenže ten má externí moduly někdy C/C++, někdy třeba v Rustu. Takže je pro "bootstrap" potřeba LLVM/Clang nebo GCC a také Rust. A kompilace Rustu trvá několik hodin i na Ryzen 5800. Takže zkompilovat nějaký projekt, třeba Sambu (která je sice napsaná v C/C++, ale na něco potřebuje Python), tak to znamená 8h reálného času jen kompilací dalších a dalších závislostí.
Proto já vždy u každého jazyka preferuji a vyžaduji pouze věci ze standardní knihovny. A u všech zmíněných jazyků je tak bohatá, že vůbec není potřeba knihovny jiných jazyků.
Proto v Golangu používám výhradně standardní knihovnu, kompilace mého programu je to 1s a kompilace Golangu samotného cca 15minut. Takže update na nejnovější verzi 1.24.2 je hotova do 20 minut, včetně všech mých programů.
Stejně tak make, meson, ninja apod. Proč jako? V každém moderním jazyku za posledních 15 let je k disposici taková hromada interních prográmků, že na Golang opravdu nikdy nepotřebuju psát Makefile, protože stačí jen go build, případně rovnou go install. S přechodem od Pythonu ke Golangu jsem rovnou odinstaloval všechny maketool, patchtools apod.
Předpokládám, že stejně je to i v Rustu. Cargo atd.
Takže už je nutnost použití Makefile nebo čehokoliv externího je známka toho, že by se ten projekt měl přepsat.
Ale tohle je můj minimalistický pohled na svět, PostgreSQL stále letí dopředu skvělou rychlostí a jestli mají tooling, který jim vyhovuje, je to OK.
(Zrovna kompilace PostgreSQL na FreeBSD je hotová do 3 minut.)
Ad „Proto já vždy u každého jazyka preferuji a vyžaduji pouze věci ze standardní knihovny. A u všech zmíněných jazyků je tak bohatá, že vůbec není potřeba knihovny jiných jazyků.“
Vidím to úplně stejně. Kolikrát říkám, že vyšší programovací jazyk (případně Unix resp. GNU/Linux) a jeho standardní knihovna jsou frameworkem samy o sobě, protože lidi na to dneska často zapomínají a mají tendenci automaticky, bez přemýšlení, zda je to nutné, tam nějaké další knihovny a frameworky natlačit (a staví „unixy“ a „lispy“ nad těmi existujícími a znovu-vynalézají kolo).
Kód, který závisí jen na standardní knihovně, je za mne ideální knihovnou nebo programem. Protože mi poskytuje ten svůj jedinečný přínos (svoje inovativní algoritmy, datové struktury), aniž by mi nutil nějaké tranzitivní závislosti. Spolupráce a kompozice s ostatním softwarem je možná, ale skrze abstraktní rozhraní a princip DI (dependency injection). Jednoduchý příklad: knihovna grafického filtru obsahuje jen ten svůj algoritmus práce s pixely, ale nenutí mi závislost na spoustě knihoven pro konkrétní grafické formáty. Načtení a uložení dat v těchto formátech probíhá vně toho filtru, případně jsou dostupné implementace nabídnuty filtru formou DI, ale závislost je maximálně na abstraktním rozhraní. Výsledkem je flexibilita a možnost použití té knihovny v libovolných prostředích a konstelacích softwarových komponent.
Někdy se těm tranzitivním závislostem vyhnout nejde (zejména těm, definujícím ta abstraktní rozhraní, nebo v případě zastřešujících knihoven a programů, jejichž přínos spočívá v tom, že poskládají dohromady nějaký funkční celek), ale čím méně jich je, tím lépe. Je dobré tyhle dvě funkce rozlišovat a izolovat – užitečné algoritmy dát do samostatných knihoven bez dalších závislostí, aby šly použít samostatně i bez toho zastřešujícího kódu.
19. 4. 2025, 10:02 editováno autorem komentáře
Posledních 15 let určitě není nutné pravidelně používat VACUUM FULL. Je to nejjednodušší kompletní údržba, ale právě vzhledem k zámkům a k faktu, že se znovu buildují indexy, tak se v kritičtějších provozech VACUUM FULL téměř nepoužívá. Paradoxně, občas se s tím ještě v některých firmách setkám, ale je to dané tím, že vůbec netuší, co dělají, a co je potřeba dělat.
Je nutné reindexovat - zvlášť u průtokových tabulek (tam degradace indexů může být rychlá). Reindexaci je ale možné provést za provozu příkazem REINDEX CONCURRENTLY (od 12ky), a dříve CREATE INDEX CONCURRENTLY (8.2 - rok 2006).
V řadě případů se dá potřeba reindexace řešit partitioningem, kdy se místo promazávání dat dropne partišna - a pak není potřeba nic reindexovat.
V 19ce by měl být k dispozici příkaz REORG CONCURRENTLY - což je vlastně VACUUM FULL CONCURRENTLY, který by neměl vyžadovat exkluzivní zámek. Nepředpokládá se, že by to byl příkaz, který by se používal pro pravidelnou údržbu.
Pokud máte potřebu někam ukládat vysokoobrátková data, zvlášť pokud máte nad tabulkama hodně indexů, tak PostgreSQL nemusí být pro Vás ta správná databáze. Nejde jen o nutnost vakuovat tabulky, ale i samotný update bude v MySQL výrazně rychlejší. Existuje extenze OrioleDB, která implementuje nový typ storage, který je navržený pro popsané použití: https://github.com/orioledb/orioledb . Je to ale zatím ve stavu public beta (jejich slovy). Co je mi známo, tak stávající storage v Postgresu se výrazněji upravovat nebude - je odladěný, a i když určitě nevyhovuje každému, tak drtivé většině uživatelů bezproblémově vyhovuje. Do Postgresu se dneska ukládá provozní monitoring kolosů jako je O2 nebo ČEZ. Dovedu si, ale představit a setkal jsem se s použitím, kde bych Postgres nenasadil, kde by MySQL nebo farma MongoDB byla určitě vhodnější.
pokud smažete celou tabulku - tak aby v ní nezůstal ani jeden řádek, tak i běžné VACUUM vám zredukuje velikost datového souboru na nulu. Když tabulku dropnete - tak se obsazené místo zruší také - nic nemusíte vacuuovat.
Existují extenze - https://www.cybertec-postgresql.com/en/products/pg_squeeze/ nebo starší pg_repack, které umí udělat totéž, co VACUUM FULL, ale zkrátí exkluzivní zámek na minimum.
Aktuálně nemám žádného zákazníka, který by musel používat VACUUM FULL. Kdybyste měli zájem - napište mi, pavel.stehule@gmail.com - mohu se podívat na vaši db. Takhle od stolu vůbec netuším, co by mohlo být důvodem, proč u vás používáte VACUUM FULL nějak často. Může to být závažný důvod, může to být nějaká blbost, nevím, ale rozhodně je to dost neobvyklé.
může se stát, že vám něco blokuje vacuum - sice běží, ale nic neudělá. Bloatnou vám tabulky, vy si pak odstavíte systém - tím eliminujete i ten blokující proces, a pak to řešíte VACUUM FULL. Je potřeba si ohlídat, že vám vacuum nic neblokuje - pokud ano, tak pak jsou s tím problémy. Vacuum vám může blokovat extrémně dlouhý dotaz, transakce, zapomenutá replikace, nedokončená 2PC transakce, ...
22. 4. 2025, 13:03 editováno autorem komentáře
Samozřejmě, nicméně pokud se použije DELETE, tak to bude o dost pomalejší (hlavně, když jsou tam nějaké vazby referenční integrity) a po VACUUM se tabulka dostane taky s velikostí na nulu. VACUUM odstraňuje prázdné datové stránky odzadu. U neprázdné stránky je redukce docela málo pravděpodobná.
Nejsem si úplně jistý, jestli jsou všichni vývojáři schopní používat TRUNCATE. Zvlášť pokud používají nějaké ORM knihovny. Některé aplikace nebo například nastavení provozu je dost divočina.
Já už PostgreSQL pomalu opouštím. Používali jsme jej ve firmě od roku 2008 až do mého odchodu v roce 2019. Naprosto skvělá databáze. Potom jsem přešel do jiné firmy, programuji v Golangu, pokud možno vše ve standardní knihovně. Aktuální horkou novinkou v Go 1.24 je SHA-3 a ten balíček, krom základních kryptografických funkcí SHA-3 128b, 256, a 512b umí také algoritmus SHAKE, kterým je možné generovat menší výstupu, třeba jen 64b. A také je v Golangu open source MIN.io. Napsal jsem o tom dva články: SHA-3 a MIN.io (tento je inspirovaný článkem z roku 2019 od Pavla Tišnovského). Takže pro programátory v Golangu je standardní knihovna použitelná už na vše (v mém případě konverze obrázků do velmi optimalizovaného PNG), komprese dat (LZW), ukládání dat (GOP).
Pomalu mi přestává stačit datový typ BYTEA v PostgreSQL, takže teď už mám nasazené MIN.io na soubory o libovolné velikosti.
Takže vše nejlepší PostgreSQL ke třicetinám, já od něj po 17 letech odcházím. Ale vy ostatní nemusíte, je to skvělá databáze, nikdy jsme nepřišli o žádná data. Jen už skutečně není vhodný pro ukládání 40GB souborů (BYTEA má limit 1GB).
Pro data o velikostech do 1GB ale stále používejte PostgreSQL, máte garantováno, že po úspěšném commitu jsou ta data velmi bezpečně uložena. A k tomu skvělé SQL.
Chtít ukládat gigabajtové soubory do DB, to je pro mne úplně z jiného světa. Neříkám, že to nejde (ostatně FS je svým způsobem taky databáze), ale databáze, zejména ty relační, mají svůj přínos jinde – hodně záznamů / řádků, sloupečků + vyhledávání v nich a další operace nad těmi atributy. Pokud je cílem ukládat velké soubory, tak je to opravdu úkol spíš pro FS nebo něco síťového s API podobným souborovému systému. Jestli ti to dlouhé roky fungovalo, tak je to důkaz toho, jak je PostgreSQL dobrá a pružná databáze.
P.S. Vím, že jsme se o tom kdysi bavili na Ábíčku, i když tehdy snad nešlo o tak velké soubory. Moje hlavní výhrady byly v tom, že je potřeba ten obsah souborů protlačit přes API/protokol té DB a přes aplikační vrstvu; ne až tak v tom, že by DB ta data nedokázala uložit. Oproti tomu když je ten velký soubor na FS, tak se dají dělat různé optimalizace a přes aplikaci to vůbec nemusí jít – ta dává jen instrukce k tomu, co se má udělat – a reálně to udělá třeba Apache nebo jiný program a Jádro (viz funkce sendfile() a zero-copy přenos bez nutnosti přepínání mezi Jádrem a uživatelským prostorem). Argumentem pro uložení všeho v DB je transakčnost a konzistence – ale to platí do doby, dokud to ta DB a aplikace v pohodě zvládají – pak už je podle mého lepší obětovat část konzistence (ve smyslu, že mi na FS můžou zůstat viset soubory, na které už v DB neukazuje žádný záznam).
Chtít ukládat gigabajtové soubory do DB, to je pro mne úplně z jiného světa.
Naprosto chápu tvé argumenty, jen jim dodám své. PostgreSQL poskytuje perfektní ACID, a pokud potřebuji ke svých binárním datům také nějaká metadata, tak uložit vše do jedné DB jedním commitem (potvrzenou transakcí) je velká výhoda. Data a metada se uloží jedním příkazem.
Stejně tak na data a metadata stačí jeden protokol. Pokud mám všechny appky napsané tak, že používají jeden síťový protokol (PostgreSQL protocol verze 2), tak mám vyřešené vše.
sendfile() a zero-copy
Tohle je implementační detail a pochybuji o tom, že to v praxi, tedy přenos dat po síti LAN nebo dokonce přes internet, kde jsou latence USA - Česko klidně 100ms, tak řešit několik volání jádra je v tomto případě zcela irelevantní. Zatímco volání jádra má latence 1us, tak následný přenos dat přes Internet je 100 000x pomalejší.
sendfile a zero-copy optimalizace jsou skvělé pro lokální programy, kde data neopustí PC do sítě. Šetří to paměť, počet callbacků do kernelu apod. Tedy všude tam kde jde o každých 100ns. To ano.
U ukladani do souboru muzes narazit na opravneni. Dalsi aspekty jsou treba pripadna migrace na jiny system. Z pohledu aplikace je to dalsi rozhrani ktery musis nejak obsluhovat.
Takze z mnoha duvodu v mnoha pripadech je ukladani souboru do databaze vlastne ta lepsi cesta.
Jasne, je to ponekud drahe, ale ...