Za prvé, moc pěkný článek. Musím pochválit.
Chtěl bych se zeptat, zda je někde nějak přehledně popsána ta replikace, především všechny ty možnosti?
Typicky mi jde o to, že mám server, který bych případně chtěl rozdělit na víc (z výkonových důvodů). Do teď byla možnost jen Slony, ale naprosto se mi příčí přístup přes triggery. Ale netušíl jsem, že existje nějaké API s hooky na replikaci, jak to funguje?
Bohužel se mi zdá, že ten nový přístup nelze použít na nic jiného, než hot standby. Nebo je nějak řešena konzistence jednotlivých serverů? Například když udělám INSERT na master serveru a pak SELECT na libovolném stroji, dostanu již pokaždé i ten nový záznam?
Teoreticky by stačilo nějak server běžící readonly přesvědčít, aby zápisy přeposlal na master server a pokračoval ve zpracování až ve chvíli, kdy záznamy bude mít u sebe. Například případ, kdy založím nový záznam v tabulce faktur a hned si ho načtu zpátky a použiju.
To je zajímavé, jen mám strach, aby to nebylo takové moc překombinované. Ikdyž tohle jeětě vypadá na únosnou mez :-)
Pochopil jsem to správně tak, že věechny ty DB stroje používají jeden sdílený adresář PG_DATA? Jestli ano, jak je pak zajištěno, že master postgres všechno víceméně okamžitě uloží na shared FS? To by se asi dalo vyřešit i tím hot standby, co umí 9.0, ale pořád mi tam chybí ta jistota, že např SELECT okamžitě po INSERTu vráti i nová data…
Data na disku konzistentní občas jsou – pokud přijde checkpoint což je v defaultu např. max 5 minut. Jinak jsou změny zachyceny pouze v cache (shared-buffers), a samozřejmě aby nedošlo ke ztrátě dat při výpadku, tak v transakčním logu. Rozdíl mezi uloženými daty a aktuálními daty je zachycen právě v transakčním logu. Nová instance db, i když pojede na daty jiné instance nebude sdílet shared-buffers. Když budete mít kliku, tak to fungovat může – ale nikdo a nic Vám to negarantuje.
Mě hlavně není jasné čeho tímhle setupem vlastně chcete dosáhnout …
I kdyby to nakrásně z nějakého záhadného důvodu fungovalo (přes Pavlovy argumenty proč to spolehlivě fungovat nebude), tak mi uniká smysl toho sdíleného disku. Replikace se v zásadě používá v případě že (a) potřebujete záložní systém a nebo (b) rozložit výkon na víc strojů:
(a) zálohování
V tomto případě většinou na slavech nepotřebujete provádět dotazy, stroj tam prostě jenom sedí a „čeká“ až produkce spadne a on se přepne do pozice mastera. Tudíž vás nějaké drobné zpoždění mezi zápisem na masteru a propagací na slave moc nevzrušuje (navíc s hot-standby to bude minimální).
Navíc ten sdílený disk představuje „single point of failure“ tj. například pokud selže hw nebo pokud master při odchodu nějak brutálně rozvrtá ten datový adresář (byť se mi nikdy nic takového nestalo), tak nemáte nic. A to je u zálohování trochu problém …
(b) rozložení výkonu
V případě databází je nejčastějším bottleneckem bezpochyby I/O (na HDD). Tím že používáte sdílený disk tak to zatížení I/O v podstatě nijak nerozkládáte protože všechno jde přes jeden diskový systém (řadič, fyzické disky, …). A navíc to jde ještě přes síť což přidává další latenci (jak moc záleží na síti, síťovkách, atd.).
Čili ani v jednom případě by použití sdíleného disku nebylo funkční řešení …
PS: Jako jo, mohli bysme se bavit o řešeních sdílených discích typu SAN apod. přes které by to teoreticky mohlo fungovat (ale ne pro PostgreSQL, viz. Pavlův příspěvek).
Ne zcela rozumím jak to SSD disky řeší …
Vycházím z toho že pokud mám I/O bottleneck na disku, nevyřeším ho tím že na stejném disku rozchodím další instanci databáze která tudíž bude užírat I/O z toho samého disku, čímž problém ještě zhorší. A to že se jedná o SSD na tomhle principu nic nemění, ne?
Navíc je otázka co je to za SSD disky (Flash vs. DRAM) a jaký typ zátěže to je (write vs. read). Např. flash SSD disky mají problémy při zápisu, kdy jsou dokonce pomalejší než tradiční disky – u DRAM SSD tohle samozřejmě neplatí.
Ale připouštím že SSD disky nijak detailně nesleduji a třeba se v poslední době udál nějaký zásadní koncepční zlom.
Nicméně SSD disky jsou obecně dražší a je otázka jestli to ve výsledku je rentabilní řešení. Navíc DB oblast je poměrně konzervativní.
Kdyz mate kvalitni storage s kterou jste se asi doposud jeste nesetkal kdyz porad trvdite ze je nejpomalejsi disk a udelate si z toho data sharing group na mainframech pripadne na POWER a nasadite shared disk db reseni – DB2 Purescale na POWER nebo Oracle RAC. nebo DB2 for z/OS tak jeden node v takovem clusteru dela cca 15–25k transakci/sekundu a ma to do 32 uzlu prakticky linearni skalovatelnost.
Pokud narikate nad pomalym diskem tak si kupte lepsi storage a vice RAM, pod 64GB na uzel nema cenu dneska jit.
1) Všimněte si prosím že můj příspěvek je formulován ve smyslu „Pokud máte problém s I/O na disku, další instance přistupující na stejný disk nepomůže.“
Nechápu vaši argumentaci ve smyslu „Ale s kvalitní storagí typu … to problém není!“
Není, to máte samozřejmě pravdu, ale to také nebylo pointou mého příspěvku. Trochu mi to připomíná vtip končící „Ale vy zase bijete černochy!“
2) Pořád mi nějak uniká jakým zázračným způsobem se ty SSD disky vyhýbají uvedenému principu „když mám problém s I/O na disku, nemá cenu tam rozjíždět další instanci.“ Možná mají vyšší propustnost, nižší latenci atd. ale ten princip pro ně pořád platí …
3) Ano, máte pravdu že s uvedenými technologiemi (alespoň s výjimkou Oracle RAC) běžně do styku nepřijdu. Jste holt lepší. Nicméně tak nějak jsem – možná mylně – předpokládal že pisatel původního příspěvku se na takovém prostředí nepohybuje. A i kdyby pohyboval, formulace mého příspěvku s tím nijak v rozporu není (viz. první odstavec).
4) Tvrdím že disk je nejčastější příčinou výkonnostních problémů na DB. Netvrdím a nikdy jsem netvrdil že to tak je vždy, za každých okolností a na každém hw. Předpokládám ale že se shodneme že na standardním hw to tak je.
5) Bez ohledu na předchozí body je to v případě PostgreSQL bezpředmětná diskuse, protože PostgreSQL provoz více instancí nad sdíleným adresářem nepodporuje.
budem sice mozno trocha off topic, lebo ako sa chova postgres neviem, kazdopadne s cimsi podobnym som sa stretol u berkeley, ktora ma podobnu funkcionalitu implementovanu uz niekolko verzii.
berkeley nedisponuje frameworkom na preposielanie write requestov z replikanta (slave-a) na master-a a co sa tyka garancie toho, ze zaznam, ktory slave vracia, je vzdy aktualny, toto berkeley zarucit nedokaze a zrejme sa to ani neda. je vsak mozne zarucit, ze databaza je v bode citania v ramci transakcie plne konzistentna najvyssim levelom separacie transakcie tak, ze pripadne novo commitnute transakcne logy sa v kontexte v minulosti zacatej transakcie neprejavia.
nezabezpeci to sice, ze bude vzdy vidno najnovsie data, ale zabezpeci to, ze v pripade dlhotrvajucej transakcie na replikantovi, ktoremu je streamovane velke mnozstvo logov bude transakcia konzistentna k bodu jej vytvorenia a neobjavia sa v nej data, ktore boli commitnute logom, ktory dorazil po zacati transakcie. hovori sa tomu snapshoting, ale netusim, ci to postgres bude vediet.
samozrejme, cim vacsi pocet takto osetrenych transakcii a cim vacsie mnozstvo commitov, tym viac pamate si to vyzaduje.
Hot standby je popsáno v dokumentaci http://developer.postgresql.org/pgdocs/postgres/index.html . Popis možných hooks bohužel nikde není – není to nic, pro běžného uživatele – ohledně replikací by bylo možné se inspirovat v Slony2. Jinak – jak slony, tak hot standby implementují asynchronní master/slave replikaci. Vy asi hledáte synchronní master/master replikaci – tu například poskytuje projekt pg_cluster – což je speciálně upravená verze PostgreSQL.
Ten popis hot standby jsem četl. Spíš jsem měl na mysli nějaký souhrn možností a jejich srovnání s nějakým výhledem do budoucna. Můj problém je podle mně docela běžný. Mám DB server, který už nestíhá, je možné pořídit více serverů, ale aplikaci není možné upravit tak, aby pracovala s více servery. A poměrně často se spoléhá na to, že pokud udělám insert/update/delete + commit, tak po commitu už tam ty data budou nebo nebudou (podle operace). Samozřejmě by se mi i líbilo, kdyby se to dostalo do stavu, kdy pád jednoho serveru pouze sníží výkon celého řešení.
Jako jediné použitelné řešení vypadá ten PgPool, který sice představuje SPOF (Single point of failure), ale to by se dalo vyřešit záložním serverem nebo nějakým záložním virtuálem.
Ak to naozaj potrebujete vyriesit skuste:
http://linux-vserver.org
Nepredstavuje to velku zataz pre server a je to spolahlivejsie ako cokolvek aplikacne riesene. My bezibe niekolko desiatok virtual servrov bez problemov.
Najprv by som chcel podakovat za pekny clanok. Pouzivame PostgreSQL uz dlhe roky pre nase Java aplikacie. Strucne:
1) Existuje nejaka statistika ako sa PostgreSQL bezne pouziva? Java backend, ine web aplikacie, … .
2) Vsetky tieto vlastnosti su fajn ale existuje plan ako ich napriklad integrovat do Hibernat-e?
3) Bude sa riesit optimalizacia JDBC drivera?
Sme focusovany na Javu ale napriklad uz iba hlupe ‚like‘ medzi cislom a retazcom bol v 8.3 zakazany. Pritom chcem obycajne „345 like 3 = true“ alebo „345 like ‚3%‘ = true“. Ano v cistom SQL sa to robi lahko tak ako to popisujete zo vselijakymi SQL extensiami ale skuste to urobit tak aby to fungovalo cez Hibernate → JDBC → Databaza. Mate problem. Takze nakoniec zistite ze mate silnu databazu s roznymi skvelymi funkciami ku ktorym sa neviete dostat.
Podpora sequncer per table – out of box, BLOBy, to su veci ktore sa stale s Javy robia dost tazko obzvlast cez Hibernate. Nesuvisi to priamo s databazou dokonca ani s JDBC drivrom ale keby ste to vyriesili vela Java developerov by vam boli vdacnych. Je pekne ze sa zaoberate partitioningom ale pokial sa potom musite potykat so zakladnymi problemami ako je BLOB a byte[] a musite si koli tomu citat 3 hodiny clanky na internete aby ste to spravne nastavili tak vas humor prejde. Pritom v Oracle a MySQL to ide bez problemov.
Napriek tomu drzim palce a dakujem za skvelu databazu.
No, on ten JDBC driver má víc much, například doporučuji dávat si velký pozor při práci s kurzory (v podstatě je vůbec nepoužívá, takže například HOLD_CURSORS_OVER_COMMIT není podporováno) a s dávkami.
V podstatě, pro nejaké „pokročilejší“ použití je potřeba zapnout debugování a zkoumat jak vlastně komunikuje se serverem.
Osobně mám pocit, že se teď pg používá nejvíc právě s Javy – bohužel v core týmu není nikdo, kdo by Javě rozuměl a měl ji v oblibě – a ti lidé, kteří píší JDBC driver mají asi dost specifický přístup :(. Je to Open Source – ta kvalita je dána lidma, kteří to píší a záleží jak moc to berou osobně. Core pg jsou všíchni céčkaři. Je to dost vidět na .NET driveru, za kterým je jeden nadšenec, a který je o dost dál.
Uz ma PG subtransakce? Tohle je vec ktera mi nejvic chybi – jak v prikazove radce (preklep v prikazu shodi celou transakci) tak i v aplikacich – treba pokud chci zmenit nejaky radek (nebo vlozit pokud neexistuje), muzu delat INSERT a v pripade vyjimky UPDATE.
A pak jeste packages – hlavne kvuli per-session promennym. Napriklad takto muze komunikovat for-each-row trigger s after-statement triggerem. Mozna se to da emulovat pomoci docasnych tabulek.
-Yenya
Packages chtějí všichni, ale nikdo neví jak na to – díky tomu, že PL v PostgreSQL není jen PLpgSQL, ale také PLPerl, PLPython a další. Osobně nečekám příliš velký pokrok – ale třeba se něco změní.
Podívej se na ON_ERROR_ROLLBACK nastavení v konzoli – mám pocit, že je to, to co chceš, nicméně jistý si nejsem – možná to bude funkční až v kombinaci s AUTOCOMMIT ON.
a) používat schémata
b) procedury psát do obyčejného souboru – jako klasický zdroják a importovat do db příkazem \i v konzoli.
c) používat kombinaci PL jazyků sql, plpgsql a plperl (případně výjmečně plperlu)
d) do kódu přídávat trasovací body – příkaz RAISE NOTICE, které jsme nemazali ale zakomentovali
+ klasika sw inženýrsví – čítelné komentáře, rozumně dlouhé procedury, atd atd další informace viz slajdy ze školení http://www.postgres.cz/index.php/Jednodenn%C3%AD_%C5%A1kolen%C3%AD_PostgreSQL#PostgreSQL_efektivn.C4.9B.2C_v.C3.BDvoj_.28ulo.C5.BEen.C3.A9_procedury.29
No je to tam dlouho – 8.1 za chvíli vyprší pětiletá podpora :)
jinak s dotazy ohledně pg http://groups.google.com/group/postgresql-cz?hl=cs
Pavel
Tak ono vytvářet spoustu savepointů asi taky není úplně optimální. V PL/pgSQL se to dá řešit celkem elegantně pomocí ošetření exceptions, s obyčejným SQL asi jenom ty savepointy).
Souhlasím že rekompilace package zásadní problém není – je ale potřeba aby všichni klienti počítali s tím že mohou po rekompilaci dostat exception a uměli na to správně zareagovat.
Nejspíš jsem to napsal špatně, omlouvám se – funkce se jmenuje listagg a je v 11 Oracle např. http://karenmorton.blogspot.com/2009/09/11gr2-listagg.html