Krátký návod jak na upgrade databázového serveru PostgreSQL na novou hlavní verzi. Před chvílí se v repositářích Debianu Jessie objevila nová verze PostgreSQL 9.4 (beta2), je to tedy vhodná příležitost, abychom si ukázali, jak lze provést upgrade dat ze starší verze.
Dump / Load
Nejbezpečnější a nejklasičtější způsob upgrade PostgreSQL server (dále jen pgsql) je dump dat ze starého serveru a jejich nahrání do serveru nového. Tato varianta bude fungovat vždy a to prakticky z jakékoliv starší verze PostgreSQL serveru.
Upozornění: Je vhodné nebo spíše nutné používat vždy příkazy z nové verze pgsql. Děláme-li například upgrade z 9.3 na 9.4, je nutné používat příkazy jako pg_dump, psql apod vždy ve verzi 9.4. Každý klient si poradí s (libovolnou) starší verzí serveru, naopak to ale neplatí.
Data ze starého serveru jednoduše uložíme do souboru obsahující sekvence SQL příkazů:
pg_dumpall -h stary_server > all.sql
A nahrajeme je do nového:
psql -h novy_server < all.sql
Pochopitelně nám nic nebrání tyto dva příkazy spojit a provádět tak dump a load současně:
pg_dumpall -h stary_server | psql -h novy_server
Jediná a podstatná nevýhoda tohoto postupu je časová náročnost. Na mém soukromém databázovém serveru trvá jen dump 100GB databáze hodinu a padesát minut. Jeho nahrátí by bylo delší, tedy upgrade tohoto databázového serveru by trval odhadem asi 5 hodin. Což je v produkčním nasazení prakticky nereálné (a to se bavíme o velmi malé databázi, v provozu máme objemy přibližně 20x větší).
pg_upgrade
Proto vývojáři PostgreSQL přišli s metodou upgrade, která pracuje přímo s datovými soubory na disku.
Použití je opět velmi jednoduché:
pg_upgrade -b oldbindir -B newbindir -d olddatadir -D newdatadir
Kde:
- oldbindir
- je adresář s binárkami staré verze (například v Debianu:
/usr/lib/postgresql/9.3/bin/
) - newbindir
- je adresář s novou verzí (
/usr/lib/postgresql/9.4/bin/
) - olddatadir
- je adresář s daty staré verze (lépe řečeno s ostrými daty, která chceme překlopit do nové verze pgsql)
- newdatadir
- je potom datový adresář nové verze (například v Debianu:
/var/lib/postgresql)/9.4/main/
)
Konkrétní adresáře se mohou u jednotlivých distribucí lišit.
Zatímco pomocí kombinace dump a load bylo možné mít zdrojový a cílový PostgreSQL server i na jiných uzlech sítě, tak příkaz pg_upgrade
je určen pro konverzi dat na místě.
Je ale o mnoho rychlejší, celý upgrade spočívá ve zkopírování datových souborů a jejich následné úpravě, pokud to rozdíl verzí vyžaduje.
Stejně jako v případě dump a load, pokud tento způsob upgrade selže, je možné se vrátit ke staré verzi, data staré verze nejsou nijak porušena. Ovšem s následující vyjímkou:
Místo kopírování souborů může pg_upgrade
použít hardlinky (parametr --link
), čímž se upgrade ještě více urychlí, ale v případě, že cokoliv selže, nebude možné použít ani původní verzi pgsql.
Debianní přístup
Nebyl by to Debian, kdyby na to neměl vlastní skript. Vzhledem k tomu, že Debian má poměrně slušně propracovanou možnost běhu více verzí pgsql vedle sebe, asi nepřekvapí, že i na upgrade dat z jedné verze do nové má vlastní skript.
Pomocí jednoduchého příkazu:
pg_upgradecluster 9.3 main
Tak snadno povýšíte svá data ze staré verze 9.3 na novou (příkaz automaticky najde nejvyšší nainstalovanou verzi, lze ji též specifikovat parametrem -v).
Ve výchozím nastavení tento skript používá metodu dump a load, ovšem lze si zvolit i metodu pomocí pg_upgrade
a to parametrem --method=upgrade
. Dokonce umí předat i parametr --link
— viz výše).
Pár slov závěrem
A to je celé. Pokud některá z pokročilejších metod selže, je vždy možné použít klasický dump / load. pg_upgrade
je velmi příjemný a rychlý způsob konverze datových souborů do nové verze a v případě použití hardlinků (což může být sice potenciálně nebezpečné, ale tak v nejhorším případě se vytáhnou zálohy) i neskutečně rychlé.
Na mém soukromém serveru s 97GB databází trvá jen dump asi dvě hodiny, pg_upgrade
(s kopírováním) byl potom hotový během 30 minut. Metodu s použitím hardlinků jsem nezkoušel, ovšem v takovém případě bude „kopírování“ hotové během několika (mili)sekund a veškerý čas tak zaberou pouze kontroly před a po upgrade. Takže několik málo minut.
Dump nikdy nedelam do SQL je to extremne neusporne a pomale. Vetsinou pouziji custom nebo directory ktery umi i paralelni zapis. Pro zalohy vetsinou pouziji ten kompaktnejsi custom.
O tom inplace upgrade jsem nevedel. Diky.
Jeste pounamka k sql dumpu – praveze nebude fungovat vzdy, nekdy lze narazit na problemy s constrainty a orderingem ddl commandu, cuz custom format resi.
pg_dumpall
parametr format nemá, proto nelze použít custom ani žádný jiný.pg_dump
je příkaz pro uložení jedné databáze, zatímcopg_dumpall
uloží do souboru celý cluster – tedy včetně definice rolí (uživatelů), skupin apod – tohle je asi nejviditelnější rozdíl.pg_dump(all)
pořadí operací řeší, jinak by byl prakticky nepoužitelný. Problémy nastávají v případech, kdy admin ukládá zvlášť DDL (--schema-only
) a zvlášť data (--data-only
). V takovém případě je „obnovení“ databáze v podstatě mravenčí práce (no, dají se vypnout triggery apod., ale i tak).(Pokud v nějaké situaci
pg_dump(all)
špatně seřadí příkazy, tak je to na bugreport.)Co se týče záloh, u takto velkých databází už je jakýkoliv dump nepříjemně velký, nedají se pořádně komprimovat a deduplikovat atd. U takto velkých serverů, pokud se jedná o virtuálku, lze dělat zálohy image celé virtuálky (a to včetně deduplikace), případně, na úrovni databáze samotné potom PITR.
Aha koukám že pg_dumpall skutečně nemá ty parametry. To je divné, zrovna u něj bych to čekal (bude patrně dávat ještě víc dat než pg_dump).
Nicméně -Fc nelze než doporučit, pokud je to tedy možné použít.
Myslím že tu chybu s pořadím jsem zaznamenal zrovna když jsem ukládal DDL zvlášť. Už si nepamatuju, bylo to rychlejší vyřešit ručně (i když mi to trvalo celkem dlouho).
U těch záloh by mě to zajímalo jak to děláš, námět na článek. Zejména zálohování celých oddílů je přeci zbytečné (na co zálohovat indexy). Opravdu se nevyplatí dělat nějaký dump pouze struktury+dat do nějakého efektivního formátu?
Ano, však jsem ti to také před lety doporučil :-)
Ono to k tomu může lákat, ale na to to opravdu určeno není.
--schema-only
se používá v případě, kdy chceš uložit schéma jak součástí zdrojáků programu pro čistou instalaci aplikace a vytvoření databázové struktury.No mě by to také zajímalo :-D Ale možná hozenou rukavici zvednu.
Tak my zálohujeme celé virtální mašiny.
Jako ono zálohování by se mělo řídit tím, co a jak je potřeba obnovit. (Mimochodem taky sis všiml, jak se často velmi důkladně popisuje způsob zálohování a potom se obnovení odbude jedním odstavcem?)
Takže je třeba si říct, zda potřebuji obnovit jednu databázi z mnoha, celý „cluster“ nebo celý server. Lze jít do dalších podrobností. A v závislosti na odpovědi na tuto otázku je třeba vybrat zálohovací řešení.
Někde se hodí dumpy, někde PITR, někde si lze dovolit databázovou službu vypnout a potom lze rsyncovat (a verzovat) celý adresář s clusterem apod.
Ale jo, asi se o tom někdy rozepíšu, ale v tomto se vůbec necítím býti odborníkem a rád bych věděl, jak se tato problematika řeší jinde. Co třeba u vás?
Pingback: Několik způsobů zálohování databáze | Heronovo
Pingback: Upgrade PostgreSQL 9.4 beta2 | Heronovo