Hlavní navigace

Udržujte si svou databázi v bezpečí s Pgpool2

26. 6. 2009
Doba čtení: 8 minut

Sdílet

Bezpečnost dat dnes znamená všechno zdvojovat. Máme dva disky, máme druhý stroj na zálohy, máme dvě linky do Internetu a nebo také dvě auta, abychom si byli jistí, že se k serverům dostaneme. Když se nám povede umístit data online na dvě místa, můžeme mluvit o úspěchu. Dnes si povíme, jak to udělat s Postgresql.

Když se podíváte na dnešní servery, tak obsahují věci jako dva zdroje, RAID 1, ECC paměti, UPS, diesel agregáty a některé třeba umí zahodit za běhu samotný procesor. Je tu ovšem jedno velké ale. Jeden server je většinou závislý na jednom poskytovateli a leží na jednom místě. Když se přižene velká voda, vznikne požár nebo stačí, aby se vyskytla chyba, se kterou si RAID 1 neporadí, tak je server offline, ať chceme nebo ne.

Opravdu jediné spolehlivé řešení je vymyslet, jak dostat data na dvě od sebe vzdálená místa, kde se budou s časem měnit. Pokud jedno z těchto úložišť vypadne, druhé ho musí zastoupit jak funkčně, tak výkonově. Ne vždy to je jednoduché a když s tím aplikace nepočítá, můžeme mít problém. Nabízí se otázka, jestli lépe nenavrhovat aplikace a neinvestovat do několika levnějších serverů místo jednoho drahého, který může skončit na naprosté banalitě.

Při mé honbě za větší spolehlivostí služeb, ať už v naší komunitní síti nebo na serveru, jsem se pokoušel právě o jejich rozdvojení na několik serverů. S některými aplikacemi to jde lépe, s některými hůře a s dalšími vůbec. Takovou nejzajímavější dvojici je webová aplikace a databázový server. Dnes používám frameworky Django a Cherrypy a s těmi lze takovéto finty vcelku jednoduše udělat. Databáze je malinko větší oříšek a největším oříškem jsou statická data jako obrázky, texty, videa atd.

Pokud jde o statický obsah, tak pro něj bylo řešení nastíněno třeba v článku o AoE. Dále se nabízí pravidelný rsync, specializované souborové systémy nebo třeba úprava (S)FTP serveru, případně něco, na co jsem ještě nenarazil a budu moc rád, když se podělíte s vlastními zkušenostmi.

Databázi jsem si nechal nakonec, protože o té bude dnešní článek. Povíme si o nástroji pgpool2, který dokáže s několika databázovými servery moc hezké věci. Konkrétně se budeme zabýval replikačním módem. Díky němu budou mít vaše aplikace přístup k databázi i za nepříznivých podmínek, kdy jeden ze serverů vypadne. Pokud se tak stane, dokáže pgpool data sesynchronizovat, resp. dá vám k tomu příležitost v nejvíce vhodnou chvíli. Pgpool2 umí následující módy:

  • Replikační
  • Load balancing
  • Paralelní
  • Master/slave

My se dnes budeme zabývat pouze replikačním módem. Ostatní ho ale mohou doplnit. Abychom se v tom neztratili, použijeme obrázek. Pokud si chcete pgpool vyzkoušet, tak si vytvořte dva až tři virtuální servery např. s Debianem a nastavte si je tak, aby k sobě měly přístup jako na obrázku.

Pgpool - schéma

Stroje označené PG1 a PG2 mají na sobě nainstalovanou databázi. Oba jsou nakonfigurované stejně a obsahují stejná data. K oběma se připojuje stroj, na kterém sice databáze není, ale je na něm nainstalováno pgpool. To je nakonfigurované v replikačním módu a připojuje se k oběma serverům. Pokud není zapnut load balancing, je jeden ze serverů jako máster a další jsou označeny jako slave. Mastera pgpool zatěžuje SELECT dotazy a INSERT posílá na všechny zúčastněné. Při zapnutém load balancingu se dotazuje pgpool serverů tak, aby si každý vzal část zátěže. Pgpool2 by se dalo označit za proxy k Postgresql serverům a umožňuje všechno, co může v této pozici nabídnout.

Když máme přichystané servery s nainstalovanými databázemi, je čas se podívat na pgpool. Ten se nastavuje ve dvou konfiguračních souborech. V /etc/pgpool.conf se nastavuje přístup k serverům a všechno co se týká chování samotného pgpool. Druhý konfigurační soubor, /etc/pool_hba.conf, má totožnou konfiguraci jako pg_hba.conf z Postgresql a omezuje přístup uživatelů k databázi.

Vzorový konfigurační soubor /etc/pgpool.conf by mohl vypadat takhle:

# Kde má pgpool naslouchat
listen_addresses = '*'
port = 5432
socket_dir = '/var/run/postgresql'

# Komunikačního manageru (nedháváme výchozí)
pcp_port = 9898
pcp_socket_dir = '/var/run/postgresql'
pcp_timeout = 10
# Pokud se nepřipojujeme lokálně, tak není potřeba
backend_socket_dir = '/var/run/postgresql'
# Počet pre-forkovaných procesů
num_init_children = 5
# Počet spojení na jeden proces
max_pool = 10
# Pokud se nic neděje 5 minut, tak se proces ukončí
child_life_time = 300
connection_life_time = 0
# Počet spojení po kterém se proces ukončí
child_max_connections = 0
authentication_timeout = 60
# Adresář s pid souborem
logdir = '/var/run/postgresql'

# Nastavení pro replikační mód
replication_mode = true
replication_strict = true
replication_timeout = 5000
load_balance_mode = true
#
replication_stop_on_mismatch = true
# Replikace SELECT dotazů
replicate_select = false
# Co se má poslat databázi, když se ukončuje spojení
reset_query_list = 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT'
print_timestamp = true
master_slave_mode = false
connection_cache = true
# Kontrola spojení se serverem
health_check_timeout = 20
# Jak často kontrolovat databázové servery v sekundách
health_check_period = 0
# Uživatel kontroly
health_check_user = 'root'
insert_lock = false
# Ignorování zbytečných mezer
ignore_leading_white_space = false
# Nastavení logování
log_statement = true
log_connections = true
log_hostname = true
# Paralelní mód
parallel_mode = false
enable_query_cache = false
pgpool2_hostname = ''

# Nastavení prvního databázového serveru
backend_hostname0 = '10.0.0.2'
backend_port0 = 5432
# Hodnota, kterou se nastavuje poměr rozdělování dotazů loadbalancingem
backend_weight0 = 1
# Nastavení druhého databázového serveru
backend_hostname1 = '10.0.0.3'
backend_port1 = 5432
backend_weight1 = 1

enable_pool_hba = false 

Konfigurační soubor jsem zbavil originálních komentářů. Ty konfiguraci v mnohém ulehčí. U některých módů potřebuje pgpool přístup do databáze a pár tabulek. U replikace to nutné není. Pokud máte databáze nastavené správně (přístup ze sítě), mělo by vám jít se teď přihlásit. Pokud tomu tak není, problém hledejte v logu a v nastavení práv u databází, případně v IP adrese, na které databáze naslouchají.

Všechno už běží dobře a může to tak běžet dál. Jednou se ovšem objeví problém a možná to ani nemusí trvat dlouho. Je dobré vědět, jak se pgpool k problému zachová. Máme-li spojení na dva databázové servery, pgpool je schopno kontrolovat jejich stav. Reaguje na problém, kdy buď jeden server neodpovídá, nemůže se k němu připojit nebo dostane zprávu o ukončení spojení. V takovém případě vstupuje do tzv. degradovaného módu a pracuje se zbývajícím databázovým serverem. Bohužel mi v tomto stavu vždy vypadlo spojení, ale to by uživatel měl poznat jen krátkodobým výpadkem, než se aplikace spojí s pgpool znovu.

Postup obnovy plnohodnotného spojení se všemi databázemi lze řešit ručně a méně ručně. Starší verze, obsažená třeba v Debianu, nemá pro synchronizaci dat obou databázích žádné nástroje a nezbývá nám nic jiného než odpojit klienty a data obnovit ručně. Druhá možnost je popisovaná třeba na jagiello.org, kde autor používá nástroje přímo v pgpoolu. Ty umí odpojit klienty a spustit námi napsané skripty. Proces se tedy zrychlí. Bohužel je pořád nutné odpojit klienty, aby nezasahovali do dat během přesunu. Zkoušel jsem pgpool z Gentoo a z Debianu, přitom v obou chyběla online obnova z odkazovaného blogpostu a v Gentoo nejsou ani nástroje na monitorování, i když se jedná o novější verzi.

Pro synchronizaci budeme potřebovat dva skripty a pro snazší průběh by měly mít stroje svoje ssh klíče navzájem. Minimalizuje se tak zadávání hesla. První skript se postará o dump celé databáze a přesune ho na vzdálený stroj.

restore.sh:
#!/bin/sh

REMOTE=10.0.0.3 # případně 10.0.0.2
USER=postgres
DUMP=dbs.sql

> $DUMP

for x in `psql -c "select datname from pg_database;" -t`; do
        if [ "$x" = "postgres" ]; then continue; fi;
        if [ "$x" = "template0" ]; then continue; fi;
        if [ "$x" = "template1" ]; then continue; fi;
        echo "Backup $x"
        pg_dump -C $x >> $DUMP
done;

bzip2 -z $DUMP

scp $DUMP.bz2 $USER@$REMOTE:~/
ssh $USER@$REMOTE "~/load.sh"
rm $DUMP.bz2 

Na něm spustí druhý skript. Ten vezme přesunutý dump, vymaže existující data a vytvoří databáze znovu.

load.sh:
#!/bin/sh

DUMP=dbs.sql

for x in `psql -c "select datname from pg_database;" -t`; do
        if [ "$x" = "postgres" ]; then continue; fi;
        if [ "$x" = "template0" ]; then continue; fi;
        if [ "$x" = "template1" ]; then continue; fi;
        echo "Remove $x"
        dropdb $x
done;

bunzip2 -d $DUMP.bz2

cat $DUMP | psql postgres
rm $DUMP 

I když máme data zdvojená, nejedná se o zálohu jako takovou. Pgpool sice pomůže, když vypadne spojení mezi aplikací a jednou z databází, ale když nějaký uživatel vymaže svoje oblíbené tabulky, tak nám to bude k ničemu. Díky pgpoolu nebudeme muset hned běžet k serveru, pokud se něco stane, a jak dobře víme, něco se stane vždy v tu nejméně vhodnou dobu.

Pgpool má také nástroje na monitorování. Přístup k nim je přes nastavený port, konkrétně přes parametr „pcp_port = 9898“. Ty nejdůležitější jsou:

pcp_detach_node     Odpojí databázi z pgpool
pcp_attach_node     Připojí databázi do pgpool
pcp_node_count      Spočítá počet připojených databází
pcp_node_info       Ukáže informace o databázi 

Pgpool označuje jednotlivé databáze za node, stejně jako to mají ve zvyku jiné zdvojující řešení. První tři parametry všech nástrojů jsou:

  • timeout Kdy má vypršet spojení
  • hostname Adresa stroje s pgpool
  • port Nastavený port pgpool na stroji

Další dva parametry jsou jméno a heslo. To se nastavuje v konfiguračním souboru /etc/pcp.conf, do kterého se uloží na každý řádek dvojice „jmeno:md5_hesla“.

Jak se jednotlivé nástroje používají, vám ukáže následující příklad:

CS24_early

$ pcp_node_count 10 localhost 9898 admin redcew
2
$ pcp_detach_node 10 localhost 9898 admin heslo 1
$ pcp_attach_node 10 localhost 9898 admin heslo 1
$ pcp_node_info 10 localhost 9898 admin heslo 1
10.0.0.3 5432 1 1073741823.500000 

Závěr

I když je pgpool komplikace, v kombinaci s dalšími postupy se z něj stává užitečný pomocník, díky kterému máte spolehlivější řešení, než když vám aplikace visí na jednom databázovém serveru. Největší komplikací je určitě obnova dat. Nejjistější je data na neaktuální databázi znovu vytvořit. Sice se může jednat o přenosy až stovek MB, ale máme jistotu, že se dostanou všechny opravdu tam, kam patří. Jak často tohle budeme dělat, je závislé na kvalitě hostingu, případně spojení mezi databázemi. Když máme každý server na jiné straně republiky nebo i světa, tak se občas nějaký komunikační šotek vyskytne. Ukázalo se, že distribuce mají různě zkompilovaný pgpool, a proto by možná vlastní kompilace nebyla od věci.

Jaké máte zkušenosti s replikací databází vy?

Byl pro vás článek přínosný?

Autor článku

Adam Štrauch je redaktorem serveru Root.cz a svobodný software nasazuje jak na desktopech tak i na routerech a serverech. Ve svém volném čase se stará o komunitní síť, ve které je již přes 100 členů.