Hlavní navigace

Slony1 - Replikace pro PostgreSQL (2)

29. 7. 2004
Doba čtení: 5 minut

Sdílet

V předchozím dílu jsme si nainstalovali Slony1 binárky. Ve druhé části seriálu je začneme používat.

Příprava systému

Vytvoříme db superuživatele slony:

sanatana# su  - pgsql
$ createuser -a -d -P slony
Enter password for new user:
Enter it again:
CREATE USER
$ exit

Přihlásíme se jako unixový uživatel slony a vytvoříme dvě databáze s nainstalovaným procedurálním jazykem pl/PgSQL. Je ovšem možné bez rizika použít i databáze stávající, protože všechny db objekty replikačního systému se instalují do samostatného schema, a jdou proto snadno zlikvidovat. Navíc má i konfigurační program slonik příkaz pro deinstalaci systému z databáze.

sanatana# su - slony
FreeBSD is started up by the program 'init'. The
first thing init does when starting multiuser mode
(ie, starting the computer up for normal use) is to
run the shell script /etc/rc. By reading /etc/rc,
you can learn a lot about how the system is put
together, which again will make you more confident
about what happens when you do something with it.
%createdb master
CREATE DATABASE
%createdb slave1
CREATE DATABASE
%createlang plpgsql master
%createlang plpgsql slave1
%

Protože replikaci budeme v praxi používat na již existující tabulky, vytvoříme si nějaká data, k čemuž dobře poslouží benchmarkovací program pgbench z distribuce Postgresu. Nakrmíme master databázi půl milionem řádků.

%pgbench -i -s 5 master
creating tables...
10000 tuples done.
500000 tuples done.
set primary key...
NOTICE:  ALTER TABLE / ADD PRIMARY KEY will create implicit index "branches_pkey" for table "branches"
NOTICE:  ALTER TABLE / ADD PRIMARY KEY will create implicit index "tellers_pkey" for table "tellers"
NOTICE:  ALTER TABLE / ADD PRIMARY KEY will create implicit index "accounts_pkey" for table "accounts"
vacuum...done.
% 

Připravíme si template soubor obsahující hesla superuživatelů, která bude administrativní program slonik potřebovat pro připojení do jednotlivých DB. Do tohoto souboru budeme později zadávat konfigurační příkazy (pochopitelně za příkaz NODE a současně před příkaz EXIT).

%cat setup.slonik
CLUSTER NAME = dharma;
NODE 1 ADMIN CONNINFO = 'host=localhost user=slony password=iehovah dbname=master';
NODE 2 ADMIN CONNINFO = 'host=localhost user=slony password=iehovah dbname=slave1';

EXIT 0;
% 

Clustery

Databáze spřátelené za účelem replikace jsou organizovány do clusterů. Jedna databáze může být současně členem více clusterů, naopak cluster může mít právě jednu řídící master databázi. V terminologii slony se jednotlivé databáze zapojené do clusteru nazývají uzly – NODE – nezávisle na tom, zda běží pod stejným postmasterem, nebo ne. Master databáze clusteru musí být na uzlu s pořadovým číslem 1. Master je velmi důležitý. Jednotlivé slave uzly lze do clusteru přidávat a odebírat, nelze však přehodit status clustermaster z jednoho uzlu na druhý, aniž bychom museli zlikvidovat celý cluster. Znovuvytvoření clusteru není zase tak náročná operace. Pokud jste si schovávali kopie konfiguračních příkazů pro slonika, odpovídá doba překonfigurování clusteru odpovídá době potřebné k resynchronizaci databází.

Status Master databáze v clusteru nemá nic společného se zdrojem dat pro replikaci, data lze replikovat i mezi jednotlivými slave databázemi nebo směrem slave – master. Jak již bylo v úvodu řečeno, Slony je single-master replikační systém. To znamená, že pokud replikujeme set tabulek, je možné do tohoto setu zapisovat právě na jednom NODE. Nezáleží na tom, zda má tento node v clusteru status master, nebo slave.

Provedeme inicializace clusteru. Na taktické místo v souboru setup.slonik přidáme příkaz: ` INIT CLUSTER ; ` a spustíme

%slonik < setup.slonik
%

V master databázi (NODE 1) bylo vytvořeno nové schema pojmenované podle clusteru a obsahující systémové tabulky replikátoru.

%psql master
master-# \dn
      List of schemas
        Name        | Owner
--------------------+-------
 _dharma            | slony

master=# set search_path='_dharma';
SET
master=# \dt
            List of relations
 Schema  |      Name      | Type  | Owner
---------+----------------+-------+-------
 _dharma | sl_config_lock | table | slony
 _dharma | sl_confirm     | table | slony
 _dharma | sl_event       | table | slony
 _dharma | sl_listen      | table | slony
 _dharma | sl_log_1       | table | slony
 _dharma | sl_log_2       | table | slony
 _dharma | sl_node        | table | slony
 _dharma | sl_path        | table | slony
 _dharma | sl_seqlog      | table | slony
 _dharma | sl_sequence    | table | slony
 _dharma | sl_set         | table | slony
 _dharma | sl_setsync     | table | slony
 _dharma | sl_subscribe   | table | slony
 _dharma | sl_table       | table | slony
 _dharma | sl_trigger     | table | slony

Nyní vytvoříme podobným způsobem stejné systémové tabulky i na druhém uzlu. Místo příkazu INIT CLUSTER použijeme příkaz STORE NODE:

STORE NODE( id = 2, COMMENT = 'Prvni slave');

Agenti

Tím jsme vytvořili potřebnou databázovou infrastrukturu a můžeme spustit agenty. Agent je program, který se předává zprávy mezi jednotlivými databázemi a zpracovává zprávy pro něj určené. Ve své činnost se podobá např. činnosti SMTP mailserveru. Pro každou databázi potřebujeme právě jednoho agenta na cluster. Pokud je databáze členem více clusterů, budete potřebovat spustit více agentů.

Replikační Agent je obsažen v programu slon. Jako parametry se mu předá jméno clusteru a potřebné informace, aby se mohl napojit do lokální databáze. Tyto informace jsou závislé na konfiguraci lokálního postgresu, který může být nastaven tak, aby autentifikoval lokální uživatele podle uid. V případě, že tomu tak není uvedeme i username a password.

%slon -d 2 dharma "dbname=slave1 host=localhost password=iehovah"
CONFIG main: local node id = 2
CONFIG main: loading current cluster configuration
CONFIG storeNode: no_id=1 no_comment='Primary Node 1'
DEBUG2 setNodeLastEvent: no_id=1 event_seq=103
DEBUG2 main: last local event sequence = 3
CONFIG main: configuration complete - starting threads
DEBUG1 localListenThread: thread starts
CONFIG enableNode: no_id=1
DEBUG1 main: running scheduler mainloop
DEBUG1 remoteWorkerThread_1: thread starts
DEBUG1 cleanupThread: thread starts
DEBUG1 syncThread: thread starts
DEBUG2 syncThread: new sl_action_seq 1 - SYNC 4
DEBUG2 localListenThread: Received event 2,4 SYNC
DEBUG2 syncThread: new sl_action_seq 1 - SYNC 5
DEBUG2 localListenThread: Received event 2,5 SYNC 

Pokud agent stávkuje a nechce se spustit s výmluvou, že nad touto databází již běží, přičemž ve skutečnosti neběží, je nutné mu pomoci SQL příkazem: DELETE FROM pg_catalog.pg_lis­tener;. Toto se stává například pokud immediate zdownujete postgesql, který během recovery databáze nemaže tuto tabulku. Vedoucí vývojového týmu PostgreSQL – Tom Lane – prohlásil, že tento bug rozhodně není jeho prioritou.

CS24_early

CONFIG main: local node id = 1
CONFIG main: loading current cluster configuration
CONFIG storeNode: no_id=2 no_comment='Prvni slave'
CONFIG main: configuration complete - starting threads
FATAL  localListenThread: Another slon daemon is serving this node already
Terminated 

Každý agent se připojí do své lokální databáze 4× a každých 10 sekund kontroluje tabulku událostí, které se následně snaží zpracovávat. Standardně jsou SYNC události generovány každých 60 sekund. Protože oba dva agenty máme v současné době připojeny pouze k jejich lokálním databázím, hromadí se nám v tabulce lokálně generované eventy, které nikdo nezpracovává. Kromě toho agent ještě provádí každých pět minut vymazání předaných eventů a po 30 minutách dokonce i s následným VACUUM.

slave1=# SELECT * from sl_event;
 ev_origin | ev_seqno | ev_timestamp        | ev_minxid |ev_maxxid | ev_type
-----------+----------+---------------------+ ----------+ ---------+ -------
         2 |        1 | 2004-06-26 20:28:56 | 1494847   | 1494848  | SYNC
         2 |        2 | 2004-06-26 20:29:56 | 1494863   | 1494864  | SYNC
         2 |        3 | 2004-06-26 20:30:57 | 1494879   | 1494880  | SYNC 

V dalším dílu spojíme databáze a podíváme se, jak funguje předávání zpráv prostřednictvím agentů mezi jednotlivými uzly.

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