Progetto

Generale

Profilo

PostgresStreamReplication » Cronologia » Versione 6

Simone Piccardi, 12-05-2022 15:27

1 1 Simone Piccardi
h1. Replicazione di PostgresSQL
2
3
*ATTENZIONE*: questo articolo è una bozza, al momento è nello stato di insieme di appunti sparsi senza un'ordine specifico
4
5
PostgreSQL supporta diversi meccanismi di replicazione, tratteremo in questo articolo solo uno di questi, la cosiddetta _streaming replication_. 
6
7 6 Simone Piccardi
8
h2. Verificare le configurazioni
9
10
Per verificare il funzionamento delle configurazioni sul master si può eseguire:
11
12
<pre>
13
postgres=# select * from pg_stat_replication;
14
-[ RECORD 1 ]----+------------------------------
15
pid              | 356531
16
usesysid         | 16384
17
usename          | replication
18
application_name | 13/main
19
client_addr      | 192.168.50.71
20
client_hostname  | 
21
client_port      | 39320
22
backend_start    | 2022-05-11 16:19:06.618997+02
23
backend_xmin     | 
24
state            | streaming
25
sent_lsn         | 0/50008A0
26
write_lsn        | 0/50008A0
27
flush_lsn        | 0/50008A0
28
replay_lsn       | 0/50008A0
29
write_lag        | 
30
flush_lag        | 
31
replay_lag       | 
32
sync_priority    | 0
33
sync_state       | async
34
reply_time       | 2022-05-12 17:23:56.62433+02
35
</pre>
36
37
e si verificano i replication slot con:
38
39
<pre>
40
postgres=# select * from pg_replication_slots;
41
-[ RECORD 1 ]-------+------------
42
slot_name           | replication
43
plugin              | 
44
slot_type           | physical
45
datoid              | 
46
database            | 
47
temporary           | f
48
active              | t
49
active_pid          | 356531
50
xmin                | 
51
catalog_xmin        | 
52
restart_lsn         | 0/50008A0
53
confirmed_flush_lsn | 
54
wal_status          | reserved
55
safe_wal_size       | 
56
</pre>
57
58
59
Per verificare il funzionamento delle configurazioni sullo slave si può eseguire:
60
61
<pre>
62
postgres=# select * from pg_stat_wal_receiver;
63
-[ RECORD 1 ]---------+---------------------------------------------------------
64
pid                   | 367679
65
status                | streaming
66
receive_start_lsn     | 0/5000000
67
receive_start_tli     | 1
68
written_lsn           | 0/50008A0
69
flushed_lsn           | 0/50008A0
70
received_tli          | 1
71
last_msg_send_time    | 2022-05-12 17:25:56.929438+02
72
last_msg_receipt_time | 2022-05-12 17:25:56.926351+02
73
latest_end_lsn        | 0/50008A0
74
latest_end_time       | 2022-05-11 17:53:50.803351+02
75
slot_name             | replication
76
sender_host           | 192.168.50.69
77
sender_port           | 5432
78
conninfo              | user=replication password=********  [...]
79
</pre>
80
81
82 1 Simone Piccardi
h2. Come ripristinare una replica
83
84 5 Simone Piccardi
Se per un qualunque motivo la _streaming replication_ si interrompe (la ragione più comune è che non si è previsto sul primario la retention di un sufficiente numero di segmenti WAL a coprire le differenze da trasmettere al secondario) occorre ripristinare manualmente da zero la stessa. Per questo motivo è sempre opportuno abilitare sul master l'uso di un _replication slot_ .
85 1 Simone Piccardi
86
Per farlo è disponibile, a partire dalla versione 9.4 di PostgreSQL il comando @pg_basebackup@ (si legga la documentazione su https://www.postgresql.org/docs/10/app-pgbasebackup.html) che consente di eseguire il ripristino direttamente dal secondario. I passi da seguire per farlo sono i seguenti:
87
88 2 Simone Piccardi
* fermare Postgres con:
89 1 Simone Piccardi
<pre>
90
service postgresql stop
91
</pre>
92
* vuotare la directory dei dati (o spostarne i contenuti altrove):
93
<pre>
94
mkdir oldpgdir/
95
mv /var/lib/postgresql/9.6/main/* oldpgdir/
96
</pre>
97
* collegarsi con l'utente postgres:
98
<pre>
99
su postgres
100
</pre>
101
* ripristinare il DB e la replicazione con:
102
<pre>
103 3 Simone Piccardi
pg_basebackup -h IP.DEL.DB.MASTER -U replication -D /var/lib/postgresql/9.6/main/ -P -Xs -R -S 'slot_name'
104 1 Simone Piccardi
</pre>
105 4 Simone Piccardi
quest'ultimo comando chiederà la password dell'utente @replication@ usato per gestire la replicazione e provvederà alla ricostruzione (si ometta @-S 'slot_name'@ se non si è creato un _replication slot_) .
106 2 Simone Piccardi
* riavviare Postgres con:
107
<pre>
108
service postgresql start
109
</pre>
110
111
h2. Verifica dello stato della replicazione
112
113 1 Simone Piccardi
Ci sono una serie di comandi per verificare lo stato della replicazione. Anzitutto si vada sullo slave e si verifichi che sia in standby  mode con (si assume di essere entrati in visualizzazione espansa con @\x on@):
114 2 Simone Piccardi
115
<pre>
116 3 Simone Piccardi
postgres=# SELECT pg_is_in_recovery();
117 2 Simone Piccardi
-[ RECORD 1 ]-----+--
118
pg_is_in_recovery | t
119
</pre> 
120
121
si può controllare lo stato della ricezione dei dati dal master (da postgres 9.6) con:
122
123
<pre>
124
postgres=# select * from pg_stat_wal_receiver;
125
-[ RECORD 1 ]---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
126
pid                   | 25684
127
status                | streaming
128
receive_start_lsn     | 7E/57000000
129
receive_start_tli     | 1
130
received_lsn          | 7E/58B33BA8
131
received_tli          | 1
132
last_msg_send_time    | 2020-02-19 17:57:20.239628+01
133
last_msg_receipt_time | 2020-02-19 17:57:20.238761+01
134
latest_end_lsn        | 7E/58B33BA8
135
latest_end_time       | 2020-02-19 17:57:20.239628+01
136
slot_name             | 
137
conninfo              | user=replication password=******** ....
138
</pre>
139
140 5 Simone Piccardi
e si può controllare quanto è passato dall'ultimo replay della replicazione con:
141 2 Simone Piccardi
142
<pre>
143
postgres=# select now()-pg_last_xact_replay_timestamp();
144
-[ RECORD 1 ]------------
145
?column? | 00:00:05.55037
146
</pre>
147 1 Simone Piccardi
148 5 Simone Piccardi
ma questa indicazione, se non è successo nulla sul master, non è significativa, perché registra solo quando è stata fatta l'ultima modifica rispetto ad adesso, che può essere avvenuto anche parecchio indietro nel tempo se nel frattempo non c'era nulla da modificare.
149 2 Simone Piccardi
150 5 Simone Piccardi
Per dare una indicazione dell'eventuale ritardo rispetto al master si può (su postgres 9.6) usare qualcosa del tipo:
151
152 2 Simone Piccardi
<pre>
153
postgres=# SELECT CASE WHEN pg_last_xlog_receive_location() = pg_last_xlog_replay_location()
154
                  THEN 0
155
                ELSE EXTRACT (EPOCH FROM now() - pg_last_xact_replay_timestamp())
156 1 Simone Piccardi
              END AS log_delay;
157
-[ RECORD 1 ]
158
log_delay | 0
159 5 Simone Piccardi
</pre>
160
161
mentre a partire da postgres 10 (i nomi delle funzioni sono cambiati) si può usare:
162
163
<pre>
164
SELECT CASE WHEN pg_last_wal_receive_lsn() = pg_last_wal_replay_lsn()                        
165
                  THEN 0                                                                        ELSE EXTRACT (EPOCH FROM now() - pg_last_xact_replay_timestamp())                              
166
              END AS log_delay;
167 2 Simone Piccardi
</pre>