Replikace

Z PostgreSQL
Skočit na navigaci Skočit na vyhledávání

Vestavěná (a)synchronní replikace - postup pro 9.1 a vyšší

Zde popsaný postup platí pro streaming replikaci. Streaming replikace vylepšuje Warm Standby a Hot Standby replikaci, tak že mezi master a standby databází otevře síťové spojení po kterém se předávají záznamy Write-Ahead Logů (WAL) z masteru na standby ihned poté, co jsou na master DB zpracovány. Na DB serveru v operačním systému jsou vidět běžící procesy walsender resp. walreceiver.

Warm Standby a Hot Standby replikace taky využívá WAL logy pro synchronizaci dat, ale v tomto případě je potřeba logy doručit z master na slave (např. přes scp). Tato konfigurace zde není popsána.

Master běží na 10.0.0.1, replika na 10.0.0.4

Pozn: Slave serverů může být několik - slave (replika) je read-only, master pouze jeden. Podmínkou je stejná verze PostgreSQL na replikovaném serveru a na replikách. Replikují se veškeré změny v databázi. Repliky mohou mít vlastní konfiguraci - podmínkou je soubor recovery.conf.

Příprava serveru, který poběží jako master

  • vytvoření účtu pod kterým poběží replikace (pro 9.0 je nutné použít účet postgres)
postgres=# CREATE ROLE replikator LOGIN REPLICATION;
CREATE ROLE
postgres=# ALTER USER replikator PASSWORD 'heslo';
ALTER ROLE
  • úpravy konfigurace postgresql.conf
listen_addresses = '*'		# what IP address(es) to listen on;
wal_level = hot_standby			# minimal, archive, or hot_standby
archive_mode = on		# allows archiving to be done
archive_command = '/bin/true'		# command to use to archive a logfile segment
max_wal_senders = 1		# max number of walsender processes
wal_keep_segments = 64		# in logfile segments, 16MB each; 0 disables
  • zpřístupnění masteru z repliky - zásah do pg_hba.conf
host     replication     replikator              10.0.0.4/32             md5
  • (nepovinné) aktivace synchronní replikace v postgresql.conf
synchronous_standby_names = '*'

Příprava serveru, který poběží jako slave

  • z repliky se přihlásit jako uživatel postgres a vymazat adresář ve kterém bude umístěn cluster repliky
  • z repliky pomocí pg_basebackup provést online zálohu masteru - (na 9.0 ručně)
[postgres@nemesis data]$ pg_basebackup -D /usr/local/pgsql/data/ -U replikator -h 10.0.0.1
Password: 
NOTICE:  pg_stop_backup complete, all required WAL segments have been archived
  • v postgresql.conf povolit hot standby režim
hot_standby = on
  • v případě, že na replice budete volat pomalé dotazy, nastavte aktivní hot_standby_feedback
hot_standby_feedback = on
  • do clusteru repliky nakopírovat soubor recovery.conf
standby_mode='on'
primary_conninfo='host=10.0.0.1 user=replikator password=heslo'
trigger_file='/usr/local/pgsql/data/failover'
  • vymazat serverlog z clusteru repliky
  • nastartovat repliku
  • log by měl obsahovat zhruba:
LOG:  database system was interrupted; last known up at 2011-09-04 17:59:03 CEST
LOG:  creating missing WAL directory "pg_xlog/archive_status"
LOG:  entering standby mode
LOG:  streaming replication successfully connected to primary
LOG:  redo starts at 0/23000020
LOG:  consistent recovery state reached at 0/24000000

Pozn: Pokud je takto nakonfigurován server, tak velice snadno - s použitím pg_basebackup můžeme provádět online full backup.V tom případě je nutné zvýšit max_wal_senders.

Monitoring běžící replikace

Master server

  • Výpis procesů OS
[root@testdb1 data]# ps -ef |grep sender
postgres  1818  1687  0 13:53 ?        00:00:00 postgres: wal sender process replikator 10.0.0.4(35948) streaming 0/130009A0
  • DB dotaz
postgres=# SELECT pg_current_xlog_location() ;
 pg_current_xlog_location 
--------------------------
 0/13000A38
(1 row)

Standby server

  • Výpis procesů OS
[root@testdb2 data]# ps -ef |grep receiver
postgres  2837  2831  0 13:53 ?        00:00:02 postgres: wal receiver process   streaming 0/130009A0
  • DB dotaz
postgres=# select pg_last_xlog_receive_location() ;
 pg_last_xlog_receive_location 
-------------------------------
 0/13000A38
(1 row)

postgres=# select pg_last_xlog_replay_location() ;
 pg_last_xlog_replay_location 
------------------------------
 0/13000A38
(1 row)

postgres=# SELECT pg_is_in_recovery();
 pg_is_in_recovery 
-------------------
 t
(1 row)

Failover

V případě, že v souboru recovery.conf použijeme parametr trigger_file (v našem případě trigger_file='/usr/local/pgsql/data/failover') stačí vytvořit prázdný soubor na který tento parametr ukazuje a DB provede recovery automaticky.

  • Provedení failoveru pomocí trigger file
[root@testdb2 ~]# su - posgres -c "touch /usr/local/pgsql/data/failover"

Výpis logu:
LOG:  trigger file found: /usr/local/pgsql/data/failover
FATAL:  terminating walreceiver process due to administrator command
LOG:  record with zero length at 0/13000C00
LOG:  redo done at 0/13000BA0
LOG:  selected new timeline ID: 2
LOG:  archive recovery complete
LOG:  database system is ready to accept connections
LOG:  autovacuum launcher started


Další možností je použít příkaz pg_ctl promote


Obnovení replikace po proceduře failover znamená vytvoření nové kopie standby DB a nastavení nové replikace jak je popsáno výše.

V pg_bench tj. při maximálním vytížení (výchozí konfigurace a IO s zablokovanou write cache (obyčejný disk v notebooku)) je režie asynchronní replikace cca 6-10%, a režie synchronní replikace cca 40% - v běžném provozu bych očekával režii znatelně nižší - pravděpodobně budete mít na svém serveru jištěné IO s aktivní write cache.

V případě, že potřebujeme automatické HA řešení existují různé projekty, které používají výše popsaný princip streaming replikace.

Pro Pacemaker + Corosync existuje projekt PAF. Je to v perlu napsaný OCF resource agent pomocí kterého je Pacemaker schopný rozpoznat stav jednotlivých PostgreSQL instancí na každém nodu: master, slave, stopped, catching up, apod. V případě, že na masteru nastane chyba, která je neopravitelná PAF provede promote vybrané standby DB jako nový master. PAF vyžaduje verzi PostgreSQL 9.3 a vyšší

Další projekt, který umožnuje postavení HA řešení je repmgr. Popis konfigurace viz níže, nebo v aktuálním taháku


Replikace a HA založená na repmgr (nutno zrevidovat)

Fakticky se jedná o nadstavbu nad vestavěnou podporou replikací v PostgreSQL 9.0 a vyšší. Tu rozšiřuje o podporu fail-over. Pracnost spojená s tímto systémem je větší než vestavěná replikace v 9.1 - naopak tento systém je možné použít i s PostgreSQL 9.1.

Master je na 10.0.0.1, slave je na 10.0.0.4.

Předpoklady: běžící sshd, možnost kopírování pomocí rsync mezi jednotlivými uzlu prostřednictvím učtu postgres.

  • nastavení hesla pro uživatele postgres, vytvoření certifikátu a jeho zkopírování na slave
[root@nemesis pavel]# passwd postgres
Changing password for user postgres.
New password: 
Retype new password: 
passwd: all authentication tokens updated successfully.
[root@nemesis pavel]# su - postgres
[postgres@nemesis ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/postgres/.ssh/id_rsa): 
Created directory '/home/postgres/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/postgres/.ssh/id_rsa.
Your public key has been saved in /home/postgres/.ssh/id_rsa.pub.
The key fingerprint is:
b6:84:3c:e2:e0:53:49:59:35:a9:53:9d:ca:f5:e8:ab postgres@nemesis
The key's randomart image is:
+--[ RSA 2048]----+
|      ..oo .     |
|     o  o.+      |
|    o  + o o     |
|   . oo.o . .    |
|  . + +.S.       |
| . + . + ..      |
|  o .   .  .     |
|   .      .      |
|        E.       |
+-----------------+

[postgres@10.0.0.1 ~]$ ssh-copy-id -i ~/.ssh/id_rsa.pub 10.0.0.4
The authenticity of host '10.0.0.4 (10.0.0.4)' can't be established.
RSA key fingerprint is b2:25:50:34:3f:93:da:60:e8:f2:36:88:51:a8:1a:ce.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.0.0.4' (RSA) to the list of known hosts.
postgres@10.0.0.4's password: 
Permission denied, please try again.
postgres@10.0.0.4's password: 
Now try logging into the machine, with "ssh '10.0.0.4'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

[postgres@nemesis ~]$ ssh 10.0.0.4
  • výše zmíněný login (ssh 10.0.0.4) by měl projít bez požadavků na heslo
  • předchozí dva body se zopakují na počítači, který má sloužit jako slave
su - postgres
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub 10.0.0.1
ssh 10.0.0.1
  • uzavřeme všechny ssh spojení
  • na masteru připravíme počáteční konfiguraci PostgreSQL
listen_addresses = "*"
wal_level = hot_standby
archive_mode=on
archive_command='/bin/true'
max_wal_senders=2
wal_keep_segments=100
hot_standby=on
  • primární server zpřístupníme replice - zásah do pg_hba.conf
host     repmgr           repmgr      10.0.0.4/32         md5
host     replication      all         10.0.0.4/32         md5
host     repmgr           repmgr      10.0.0.1/32         md5
host     replication      all         10.0.0.1/32         md5
  • heslo uživatele uloží v dalším kroku do .pgpass
  • restart masteru
  • na replice odstraníme obsah clusteru
/etc/init.d/postgresql stop
cd /var/lib/pgsql/data
rm -rf *
  • na slavu přeložíme repmgr. K dispozici musí být devel knihovny PostgreSQL. Tento krok je nutné zopakovat i na primárném serveru (masteru)
tar xvfz repmgr-1.1.0.tar.gz
cd repmgr-1.1.0
make USE_PGXS=1
su
make USE_PGXS=1 install
  • zpět na master - založíme db repmgr a uživatele repmgr - uživatel repmgr musí být superuser
[postgres@10.0.0.1]$ createdb repmgr;
[postgres@10.0.0.1]$ createuser repmgr
Shall the new role be a superuser? (y/n) y
postgres=# ALTER USER repmgr PASSWORD 'heslo';
ALTER ROLE
  • ověříme přístup ze slave na master
su postgres
echo '10.0.0.1:5432:repmgr:repmgr:heslo' >> .pgpass
chmod 0600 ~/.pgpass
psql -h 10.0.0.1 -U repmgr repmgr
  • klonujeme master na slave (pozor - je nutne zadat port, přestože je standardní)
[postgres@10.0.0.4]$ repmgr -D /usr/local/pgsql/data -U repmgr -p 5432 -d repmgr -R postgres --verbose standby clone 10.0.0.1
...
reomgr standby clone complete
  • na všech uzlech vytvoříme konfigurační soubor /usr/local/pgsql/repmgr/repmgr.conf podle vzoru:
[root@10.0.0.1]# cat /usr/local/pgsql/repmgr/repmgr.conf 
cluster=test
node=1
conninfo='host=10.0.0.1 user=repmgr dbname=repmgr password=heslo'
  • registrace masteru
[root@10.0.0.1]# repmgr -f /usr/local/pgsql/repmgr/repmgr.conf --verbose master register
Opening configuration file: /usr/local/pgsql/repmgr/repmgr.conf
repmgr connecting to master database
repmgr connected to master, checking its state
master register: creating database objects inside the repmgr_test schema
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "repl_nodes_pkey" for table "repl_nodes"
Master node correctly registered for cluster test with id 1 (conninfo: host=10.0.0.1 user=repmgr dbname=repmgr password=heslo)
  • na slave je nutné do souboru recovery.conf dopsat přihlašovací údaje pro login na master
standby_mode = 'on'
primary_coninfo = 'host=10.0.0.1 port=5432 user=repmgr password=heslo'
  • registrace slave
[root@nemesis data]# /etc/init.d/pgsql start
Starting PostgreSQL: ok
[root@10.0.0.4 data]# repmgr -f /usr/local/pgsql/repmgr/repmgr.conf --verbose standby register
Opening configuration file: /usr/local/pgsql/repmgr/repmgr.conf
repmgr connecting to standby database
repmgr connected to standby, checking its state
repmgr connecting to master database
finding node list for cluster 'test'
checking role of cluster node 'host=10.0.0.1 user=repmgr dbname=repmgr password=heslo'
repmgr connected to master, checking its state
repmgr registering the standby
repmgr registering the standby complete
  • na slave nastartujeme repmgrd
[root@10.0.0.4]# repmgrd -f /usr/local/pgsql/repmgr/repmgr.conf --verbose > /usr/local/pgsql/repmgr/repmgr.log 2>&1

[root@10.0.0.4 pavel]# tail -f /usr/local/pgsql/repmgr/repmgr.log 
repmgrd Connecting to database 'host=10.0.0.4 user=repmgr dbname=repmgr password=heslo'
repmgrd Connected to database, checking its state
repmgrd Connecting to primary for cluster 'test'
finding node list for cluster 'test'
checking role of cluster node 'host=10.0.0.1 user=repmgr dbname=repmgr password=heslo'
repmgrd Checking cluster configuration with schema 'repmgr_test'
repmgrd Checking node 2 in cluster 'test'
repmgrd Starting continuous standby node monitoring
  • na slave se lze dotázat na stav replikace
repmgr=# select * from repmgr_test.repl_status ;
─[ RECORD 1 ]─────────────┬──────────────────────────────
primary_node              │ 1
standby_node              │ 2
last_monitor_time         │ 2011-09-05 18:00:44.277306+02
last_wal_primary_location │ 0/5B186764
last_wal_standby_location │ 0/5B186764
replication_lag           │ 0 bytes
apply_lag                 │ 0 bytes
time_lag                  │ 00:00:02.639117