Tři způsoby upgrade PostgreSQL

PostgreSQL logoKrá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.

Příspěvek byl publikován v rubrice Databáze, Debian, Linux, PostgreSQL. Můžete si uložit jeho odkaz mezi své oblíbené záložky.

7 komentářů: Tři způsoby upgrade PostgreSQL

  1. lzap napsal:

    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.

  2. lzap napsal:

    Jeste pounamka k sql dumpu – praveze nebude fungovat vzdy, nekdy lze narazit na problemy s constrainty a orderingem ddl commandu, cuz custom format resi.

    • Heron napsal:

      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ímco pg_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.

      • lzap napsal:

        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?

        • Heron napsal:

          Nicméně -Fc nelze než doporučit, pokud je to tedy možné použít.

          Ano, však jsem ti to také před lety doporučil :-)

          Myslím že tu chybu s pořadím jsem zaznamenal zrovna když jsem ukládal DDL zvlášť.

          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.

          U těch záloh by mě to zajímalo jak to děláš, námět na článek.

          No mě by to také zajímalo :-D Ale možná hozenou rukavici zvednu.

          Zejména zálohování celých oddílů je přeci zbytečné (na co zálohovat indexy).

          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?

  3. Pingback: Několik způsobů zálohování databáze | Heronovo

  4. Pingback: Upgrade PostgreSQL 9.4 beta2 | Heronovo

Komentáře nejsou povoleny.