Názory k článku PostgreSQL 13 s řadou důležitých interních optimalizací

  • Článek je starý, nové názory již nelze přidávat.
  • 20. 5. 2020 8:19

    Miroslav Šilhavý

    DROP DATABASE FORCE je příjemné vylepšení pro správu. Do teď jsem musel nejdřív odpojovat uživatele a pak teprve provést drop (taky žádná věda, ale přišlo mi to zbytečné).

    Na co jsem však nepřišel je, jak bezpečně založit databázi a omezit spojení jen na superusera nebo na vybraného usera (např. ownera). Potřebuji, aby se do databáze nemohl dostat nikdo jiný, dokud není založená a připravená. Zatím to nouzově řeším tak, že omezím počet spojení do databáze na jedno a doufám, že můj script bude právě tím prvním a jediným povoleným spojením. Teprve po připravení zrušuji to omezení.

    V 99,9 % případů to funguje, ale co si budeme povídat, je to založené na doufání, že se mi ve zlomku okamžiku mezi CREATE DATABASE a připojením zrovna nepřipojí nikdo jiný.

    Existuje na to nějaké rozumnější řešení?

  • 20. 5. 2020 9:24

    Pavel Stěhule

    Z mně neznámého důvodu mi nefunguje REVOKE CONNECT ON template1 FROM public. Ale zafungovala mi posloupnost příkazů:

     create database omega10 ALLOW_CONNECTIONS = false;
    revoke connect on database omega10 from public;
    alter database omega10 allow_connections = true;

    Takto se k databázi může připojit pouze vlastník nebo superuser, a v žádném okamžiku se tam nemůže připojit kdokoliv další.

    Ono i kdyby se Vám tam kdokoliv další připojil, tak maximálně může udělat nějakou zlomyslnost v public schématu a nikde jinde. Do privátních schémat nikdo nemůže - takže hodně silným zabezpečením je REVOKE ALL ON SCHEMA public FROM public. Zase mohou přestat fungovat skripty (aplikační), které počítají s defaultním nastavením public schéma.

    20. 5. 2020, 09:25 editováno autorem komentáře

  • 20. 5. 2020 9:41

    Pavel Stěhule

    Přenášet databázové ACL 1:1 z template1 věcně nelze, a pro nikoho to zatím nebylo natolik důležité aby to řešil. Nově vytvořená databáze má NULL acl - což znamená, že se bezpečnostní politika vychází pouze z pg_hba.conf a pro každou databázi, pokud je třeba, se musí nastavit zvlášť.

  • 20. 5. 2020 10:37

    Miroslav Šilhavý

    Zase mohou přestat fungovat skripty (aplikační), které počítají s defaultním nastavením public schéma.

    Mně přijde celá "filozofie" schematu public trochu schizofrenní. Rozumím jejímu (původnímu) účelu. V praxi ale spíš vidím, že public funguje jako fallback pro nepozorné. Zapomenu uvést v dotazech schema (zejména při CREATE) a šup, magie search_path mě zachrání a vše zdánlivě projde a usadí se v publicu. Pak člověk najde v databázi pozakládané views, procedury a další třeba i dvakrát - jednou v publicu, jednou ve správném schematu. Nejlépe v odlišných verzích.

    Zrovna implicitní (z template1 přenášené) REVOKE ALL ON SCHEMA public FROM public by bylo hodně šikovné na správu a hledání chyb svých i druhých. Třeba i těch aplikací, které spoléhají na jeho výchozí nastavení.

  • 20. 5. 2020 11:04

    Pavel Stěhule

    Je to kompromis mezi přidáním nové zásadní změny architektury - schémata, search_path a zachování zpětné kompatibility pro aplikace, které schémata explicitně nepoužívají. A jako každý kompromis to má nějaké nevýhody, zvlášť pro uživatele, kteří databázi používají mechanicky (bez znalostí, jak funguje), a takových je v praxi asi dnes většina (bohužel - a také nelze rozumět všemu).

    U jednoho zákazníka jsem narazil na "těžké" problémy s administrací PG, právě proto, že v databázích neměl public schéma, nicméně člověk, který tomu rozuměl, a nakonfiguroval search_path z té firmy odešel, a jeho nástupci o Postgresu nevěděli téměř nic a bez "publicu" jim nefungovaly a rady postupy z Stack Overflow.

    Souhlasím, - schéma public jde proti účelu schémat v Postgresu (bacha je to něco jiného než v Oraclu), ale je to tam proto, aby se udržela rozumná úroveň zpětné kompatibility. Taková řešení málokdy jde udělat bez kompromisů u kterých 100% víte, že to není ideální. Ale bez alespoň rozumné garance zpětné kompatibility by Váš produkt téměř nikdo nepoužíval. A opravdu je potřeba spíš předpokládat nulové znalosti uživatelů a tím pádem téměř minimální inteligenci při používání produktu (spíš nulovou).

    Postgres měl v jedné verzi feature flagy, a bylo to něco, co uživatelé vůbec nezvládali. U produktu, který je 25 let starý najdete víc takových kompromisů - třeba v Postgresu pekelná past pro začátečníky je výchozí celočíselné dělení pro celá čísla. Na druhou stranu v tomhle ohledu jsou starší a tím pádem horší produkty. Oracle bude letos 45.

    20. 5. 2020, 11:04 editováno autorem komentáře

  • 20. 5. 2020 12:56

    Miroslav Šilhavý

    @Pavel Stěhule

    Zpětná kompatibilita je opravdu důležitá. Nevíte, jestli Postgres neuvažuje o zavedení nějakých compatibility levelů, podobně jak to má např. MS SQL? To mi přijde jako schůdná cesta, jak publiku sdělovat část best practices a zlepšovat stav i do budoucna. Bez toho je bezradný i administrátor. Ještě je docela schůdné si vytvořit vícero template databází a volit je podle možností aplikace (např. vynechat schema public nebo na něm odepřít přístupy). Spousta dalších direktiv se ale musí nastavit přímo v postgresql.conf a tam i správce musí (ač by třeba chtěl něco zlepšit) kompromis, nebo provozovat vícero instancí postgresu paralelně (každá s jiným nastavením). Podobně by se hodily i client_ výchozí hodnoty per database a ne per instance...

    Přijde mi, že se postgres zaměřuje na výkon (skvěle!, je to jeho velká přednost), ale na spravovatelnost se možná maličko zapomíná.

  • 20. 5. 2020 13:36

    Pavel Stěhule

    Co vím, tak žádné compatibility levely a podobné funkce nebudou. Kdysi se to zkoušelo (někdy možná v 7 řadě) a zkušenosti, co s tím byly, děsí ty hlavní vývojáře dodnes. Prostě Postgres garantuje absolutní kompatibilitu v rámci major verze a její 5 leté podpory. Ono zase těch nekompatibilit opravdu u drtivé většiny uživatelů je minimálně.

    Některé věci by bylo možné podporovat docela jednoduše, u některých se zase neví, jestli je to chyba nebo vlastnost, a zrovna například u optimalizací udržovat paralelně několik variant optimalizátoru není udržitelné. Prostě, když aplikace nezafunguje, tak je potřeba sáhnout do aplikace, protože jedině tam je možné problém vyřešit. A pokud to nelze, tak je možné (samozřejmě s určitými riziky) zůstat na poslední verzi, která funguje.

    Co se týká konfigurace, tak většinu věcí můžete nakonfigurovat speciálně pro databázi ALTER DATABASE nebo pro uživatele ALTER ROLE. A to co nejde, tak nejde z důvodu architektury. Pokud je shared buffers per instance, tak jej nelze konfigurovat per databáze. Pokud myslíte spravovatelností to, že admin může přiohýbnout chování databáze víc než nastavením pár parametrů, tak to v Postgresu asi nikdy nebude. Naopak cílem je, aby databáze byla jednoduše administrovatelná, aby to co jde, bylo relativně jednoduché - vůči Oracle je to triviální (záměrně).

  • 20. 5. 2020 13:43

    Miroslav Šilhavý

    Co se týká konfigurace, tak většinu věcí můžete nakonfigurovat speciálně pro databázi ALTER DATABASE nebo pro uživatele ALTER ROLE.

    Např. per instance nastavený search_path, datestyle, timezone, client_min_messages a podobné proměnné mi právě přijde, že by ulehčilo mít per database nebo per role. V 95 % případů stačí default, v ostatních případech se to dá nastavit z klienta. ALE jsou i situace, že některé aplikace neumí nic nastavit (výrobce už nepodporuje změny) a pak by se hodilo mít to per database.

  • 21. 5. 2020 11:29

    ďobo

    No a co takové staré dobré hba.conf?
    Pokud se připájíte lokálně na soket, tak je to jasné a pokud po síti, tak do hba.confu jen vaší IP a nic jiného...