sql >> Databasteknik >  >> RDS >> PostgreSQL

Använda PostgreSQL-replikeringsplatser

Vad är replikeringsplatser?

Förr i tiden när "replikeringsplatser" ännu inte introducerades, var det en utmaning att hantera WAL-segmenten. I standardströmningsreplikering har mastern ingen kunskap om slavstatusen. Ta exemplet med en master som utför en stor transaktion, medan en standby-nod är i underhållsläge under ett par timmar (som att uppgradera systempaketen, justera nätverkssäkerhet, uppgradering av hårdvara, etc.). Vid något tillfälle tar mastern bort sin transaktionslogg (WAL-segment) när kontrollpunkten passerar. När slaven är avstängd med underhåll, har den möjligen en enorm slavfördröjning och måste komma ikapp mastern. Så småningom kommer slaven att få ett ödesdigert problem som nedan:

LOG:  started streaming WAL from primary at 0/73000000 on timeline 1

FATAL:  could not receive data from WAL stream: ERROR:  requested WAL segment 000000010000000000000073 has already been removed

Det typiska tillvägagångssättet är att ange i din postgresql.conf ett WAL-arkivskript som kopierar WAL-filer till en eller flera långtidsarkiveringsplatser. Om du inte har några väntelägen eller andra strömmande replikeringsklienter, kan i princip servern kassera WAL-filen när arkivskriptet är klart eller svarar OK. Men du behöver fortfarande några nya WAL-filer för kraschåterställning (data från de senaste WAL-filerna spelas upp under kraschåterställning. I vårt exempel på en standby-nod som är placerad under en lång underhållsperiod uppstår problem när den kommer tillbaka online och frågar den primära för en WAL-fil som den primära inte längre har, då misslyckas replikeringen.

Detta problem åtgärdades i PostgreSQL 9.4 via "Replication Slots".

Om du inte använder replikeringsplatser är ett vanligt sätt att minska risken för misslyckad replikering att ställa in wal_keep_segments tillräckligt högt så att WAL-filer som kan behövas inte roteras eller återvinns. Nackdelen med detta tillvägagångssätt är att det är svårt att avgöra vilket värde som är bäst för din installation. Du behöver inte underhåll på en daglig basis eller så behöver du inte behålla en stor hög med WAL-filer som äter upp din disklagring. Även om detta fungerar, är det inte en idealisk lösning eftersom risken för diskutrymme på mastern kan göra att inkommande transaktioner misslyckas.

Alternativa metoder för att inte använda replikeringsplatser är att konfigurera PostgreSQL med kontinuerlig arkivering och tillhandahålla ett restore_command för att ge repliken åtkomst till arkivet. För att undvika att WAL byggs upp på den primära kan du använda en separat volym eller lagringsenhet för WAL-filerna, t.ex. SAN eller NFS. En annan sak är med synkron replikering eftersom det kräver att primär måste vänta på standby-noder för att begå transaktion. Detta betyder att det säkerställer att WAL-filer har applicerats på standbynoderna. Men ändå är det bäst att du tillhandahåller arkiveringskommandon från den primära så att när WAL är återvunnen i den primära, kan du vara säker på att du har WAL-säkerhetskopior i händelse av återställning. Även om synkron replikering i vissa situationer inte är en idealisk lösning eftersom den kommer med vissa prestandakostnader jämfört med asynkron replikering.

Typer av replikeringsplatser

Det finns två typer av replikeringsplatser. Dessa är:

Fysiska replikeringsplatser 

Kan användas för standard strömmande replikering. De kommer att se till att data inte återvinns för tidigt.

Logiska replikeringsplatser

Logisk replikering gör samma sak som fysiska replikeringsplatser och används för logisk replikering. De används dock för logisk avkodning. Tanken bakom logisk avkodning är att ge användare en chans att bifoga transaktionsloggen och avkoda den med en plugin. Det gör det möjligt att extrahera ändringar som gjorts i databasen och därför i transaktionsloggen i vilket format som helst och för alla ändamål.

I den här bloggen kommer vi att använda fysiska replikeringsplatser och hur man uppnår detta med ClusterControl.

Fördelar och nackdelar med att använda replikeringsplatser

Replikeringsplatser är definitivt fördelaktiga när de väl har aktiverats. Som standard är "Replication Slots" inte aktiverade och måste ställas in manuellt. Bland fördelarna med att använda replikeringsplatser är

  • Se till att mastern behåller tillräckligt med WAL-segment för att alla repliker ska kunna ta emot dem
  • Förhindrar mastern från att ta bort rader som kan orsaka återställningskonflikt på replikerna
  • En master kan bara återvinna transaktionsloggen när den har förbrukats av alla repliker. Fördelen här är att en slav aldrig kan hamna på efterkälken så mycket att en omsynkronisering behövs.

Replikeringsplatser kommer också med några varningar.

  • En föräldralös replikeringsplats kan orsaka obegränsad disktillväxt på grund av upphopade WAL-filer från mastern
  • Slavnoder som placeras under långvarigt underhåll (som dagar eller veckor) och som är bundna till en replikeringsplats kommer att ha obegränsad disktillväxt på grund av WAL-filer som staplas upp från mastern

Du kan övervaka detta genom att fråga pg_replication_slots för att fastställa vilka platser som inte används. Vi återkommer om detta lite senare.

Använda replikeringsplatser 

Som nämnts tidigare finns det två typer av replikeringsplatser. För den här bloggen kommer vi att använda fysiska replikeringsplatser för strömmande replikering.

Skapa en replikeringsplats

Det är enkelt att skapa en replikering. Du måste anropa den befintliga funktionen pg_create_physical_replication_slot för att göra detta och måste köras och skapas i masternoden. Funktionen är enkel,

maximus_db=# \df pg_create_physical_replication_slot

Schema              | pg_catalog

Name                | pg_create_physical_replication_slot

Result data type    | record

Argument data types | slot_name name, immediately_reserve boolean DEFAULT false, OUT slot_name name, OUT xlog_position pg_lsn

Type                | normal

t.ex. Skapar en replikeringsplats med namnet slot1,

postgres=# SELECT pg_create_physical_replication_slot('slot1');

-[ RECORD 1 ]-----------------------+---------

pg_create_physical_replication_slot | (slot1,)

Replikeringsplatsnamnen och dess underliggande konfiguration är endast systemomfattande och inte klusteromfattande. Till exempel, om du har nodA (nuvarande master) och standbynoder nodB och nodC, och skapar luckan på en masternodA nämligen "slot1", då kommer inte data att vara tillgänglig för nodB och nodC. Därför, när failover/växling är på väg att ske, måste du återskapa de platser du har skapat.

Släpp en replikeringsplats

Oanvända replikeringsplatser måste släppas eller tas bort. Som nämnts tidigare, när det finns föräldralösa replikeringsplatser eller -platser som inte har tilldelats någon klient- eller väntelägesnod, kan det leda till gränslösa problem med diskutrymme om de lämnas osläppta. Så det är mycket viktigt att dessa måste släppas när de inte längre används. För att släppa det, anropa helt enkelt pg_drop_replication_slot. Denna funktion har följande definition:

maximus_db=# \df pg_drop_replication_slot

Schema              | pg_catalog

Name                | pg_drop_replication_slot

Result data type    | void

Argument data types | name

Type                | normal

Att släppa det är enkelt:

maximus_db=# select pg_drop_replication_slot('slot2');

-[ RECORD 1 ]------------+-

pg_drop_replication_slot |

Övervaka dina PostgreSQL-replikeringsplatser

Att övervaka dina replikeringsplatser är något du inte vill missa. Samla bara informationen från view pg_replication_slots i den primära/masternoden precis som nedan:

postgres=# select * from pg_replication_slots;

-[ RECORD 1 ]-------+-----------

slot_name           | main_slot

plugin              |

slot_type           | physical

datoid              |

database            |

active              | t

active_pid          | 16297

xmin                |

catalog_xmin        |

restart_lsn         | 2/F4000108

confirmed_flush_lsn |

-[ RECORD 2 ]-------+-----------

slot_name           | main_slot2

plugin              |

slot_type           | physical

datoid              |

database            |

active              | f

active_pid          |

xmin                |

catalog_xmin        |

restart_lsn         |

confirmed_flush_lsn |

Resultatet ovan visar att main_slot har tagits, men inte main_slot2.

En annan sak du kan göra är att övervaka hur mycket eftersläpning du har. För att uppnå detta kan du helt enkelt använda frågan baserad på exempelresultatet nedan:

postgres=# SELECT redo_lsn, slot_name,restart_lsn, 

round((redo_lsn-restart_lsn) / 1024 / 1024 / 1024, 2) AS GB_behind 

FROM pg_control_checkpoint(), pg_replication_slots;

redo_lsn    | slot_name | restart_lsn | gb_behind 

------------+-----------+-------------+-----------

 1/8D400238 |     slot1 | 0/9A000000 | 3.80

Men redo_lsn finns inte i 9.6, ska använda redo_location, så i 9.6,

imbd=# SELECT redo_location, slot_name,restart_lsn, 

round((redo_location-restart_lsn) / 1024 / 1024 / 1024, 2) AS GB_behind 

FROM pg_control_checkpoint(), pg_replication_slots;

-[ RECORD 1 ]-+-----------

redo_location | 2/F6008BE0

slot_name     | main_slot

restart_lsn   | 2/F6008CC0

gb_behind     | 0.00

-[ RECORD 2 ]-+-----------

redo_location | 2/F6008BE0

slot_name     | main_slot2

restart_lsn   | 2/F6008CC0

gb_behind     | 0.00

Systemvariabelkrav

Implementering av replikeringsplatser kräver manuell inställning. Det finns variabler som du måste tänka på som kräver ändringar och specificeras i din postgresql.conf. Se nedan:

  • max_replication_slots – Om satt till 0 betyder detta att replikeringsplatser är helt inaktiverade. Om du använder PostgreSQL <10 versioner, måste denna plats specificeras annat än 0 (standard). Sedan PostgreSQL 10 är standardvärdet 10. Denna variabel anger det maximala antalet replikeringsplatser. Om du ställer in det till ett lägre värde än antalet befintliga replikeringsplatser kommer servern att förhindras från att starta.
  • wal_level – måste åtminstone vara replika eller högre (replika är standard). Om du ställer in hot_standby eller arkiv mappas till replik. För en fysisk replikeringsplats räcker replika. För logiska replikeringsplatser är logisk att föredra.
  • max_wal_senders – inställd på 10 som standard, 0 i version 9.6 vilket betyder att replikering är inaktiverat. Vi föreslår att du ställer in detta till minst 16, särskilt när du kör med ClusterControl.
  • hot_standby – i versioner <10 måste du ställa in detta till på vilket är av som standard. Detta är viktigt för standbynoder, vilket innebär att när påslaget kan du ansluta och köra frågor under återställning eller i standbyläge.
  • primary_slot_name –  den här variabeln ställs in via recovery.conf på standbynoden. Detta är kortplatsen som ska användas av mottagaren eller standbynoden vid anslutning till sändaren (eller primär/master).

Du måste notera att dessa variabler oftast kräver en omstart av databastjänsten för att kunna ladda om nya värden.

Använda replikeringsplatser i en ClusterControl PostgreSQL-miljö

Låt oss nu se hur vi kan använda fysiska replikeringsplatser och implementera dem i en Postgres-installation som hanteras av ClusterControl.

Isättning av PostgreSQL-databasnoder

Låt oss börja distribuera ett 3-nods PostgreSQL-kluster med ClusterControl med PostgreSQL 9.6-version den här gången.

ClusterControl kommer att distribuera noder med följande systemvariabler definierade baserat på deras standardinställningar eller justerade värden. I:

postgres=# select name, setting from pg_settings where name in ('max_replication_slots', 'wal_level', 'max_wal_senders', 'hot_standby');

         name          | setting 

-----------------------+---------

 hot_standby           | on

 max_replication_slots | 0

 max_wal_senders       | 16

 wal_level             | replica

(4 rows)

I versioner PostgreSQL> 9.6 är max_replication_slots standardvärde 10 som är aktiverat som standard men inte i 9.6 eller lägre versioner som är inaktiverat som standard. Du måste tilldela max_replication_slots högre än 0. I det här exemplet satte jag max_replication_slots till 5.

[email protected]:~# grep 'max_replication_slots' /etc/postgresql/9.6/main/postgresql.conf 

# max_replication_slots = 0                     # max number of replication slots

max_replication_slots = 5

och startade om tjänsten,

[email protected]:~# pg_lsclusters 

Ver Cluster Port Status Owner    Data directory Log file

9.6 main    5432 online postgres /var/lib/postgresql/9.6/main pg_log/postgresql-%Y-%m-%d_%H%M%S.log



[email protected]:~# pg_ctlcluster 9.6 main restart

Ställa in replikeringsplatserna för primära och standbynoder

Det finns inget alternativ i ClusterControl för att göra detta, så du måste skapa dina slots manuellt. I det här exemplet skapade jag platserna i den primära i värd 192.168.30.100:

192.168.10.100:5432 [email protected]_db=# SELECT pg_create_physical_replication_slot('slot1'), pg_create_physical_replication_slot('slot2');

 pg_create_physical_replication_slot | pg_create_physical_replication_slot 

-------------------------------------+-------------------------------------

 (slot1,)                            | (slot2,)

(1 row)

Kontrollera vad vi just har skapat visar,

192.168.10.100:5432 [email protected]_db=# select * from pg_replication_slots;

 slot_name | plugin | slot_type | datoid | database | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn 

-----------+--------+-----------+--------+----------+--------+------------+------+--------------+-------------+---------------------

 slot1     | | physical  | | | f      | | |       | | 

 slot2     | | physical  | | | f      | | |       | | 

(2 rows)

Nu i standbynoderna måste vi uppdatera recovery.conf och lägga till variabeln primary_slot_name och ändra application_name så att det är lättare att identifiera noden. Så här ser det ut i värd 192.168.30.110 recovery.conf: 

[email protected]:/var/lib/postgresql/9.6/main/pg_log# cat ../recovery.conf 

standby_mode = 'on'

primary_conninfo = 'application_name=node11 host=192.168.30.100 port=5432 user=cmon_replication password=m8rLmZxyn23Lc2Rk'

recovery_target_timeline = 'latest'

primary_slot_name = 'slot1'

trigger_file = '/tmp/failover_5432.trigger'

Gör samma sak också i värd 192.168.30.120 men ändrade applikationsnamnet och ställde in primär_slot_name ='plats2'.

Kontrollerar replikeringsplatsens hälsa:

192.168.10.100:5432 [email protected]_db=# select * from pg_replication_slots;

 slot_name | plugin | slot_type | datoid | database | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn 

-----------+--------+-----------+--------+----------+--------+------------+------+--------------+-------------+---------------------

 slot1     | | physical  | | | t      | 24252 | |       | 0/CF0A4218 | 

 slot2     | | physical  | | | t      | 11635 | |       | 0/CF0A4218 | 

(2 rows)

Vad behöver du mer?

Eftersom ClusterControl inte stöder replikeringsplatser för närvarande finns det saker som du måste ta hänsyn till. Vad är dessa? Låt oss gå in på detaljer.

Failover/Switchover Process

När en automatisk failover eller övergång via ClusterControl har försökts, kommer platser inte att behållas från de primära och på standbynoderna. Du måste återskapa detta manuellt, kontrollera variablerna om de är korrekt inställda och ändra recovery.conf därefter.

Återbygga en slav från en mästare

När man bygger om en slav, kommer recovery.conf inte att behållas. Detta innebär att dina recovery.conf-inställningar som har det primära_slot_name kommer att raderas. Du måste ange detta manuellt igen och kontrollera vyn pg_replication_slots för att avgöra om platser används korrekt eller lämnas föräldralösa.

Om du vill bygga om slav-/väntelägesnoden från en master kan du behöva överväga att ange variabeln PGAPPNAME env precis som kommandot nedan:

$ export PGAPPNAME="app_repl_testnode15"; /usr/pgsql-9.6/bin/pg_basebackup -h 192.168.10.190 -U cmon_replication -D /var/lib/pgsql/9.6/data -p5434 -W -S main_slot -X s -R -P

Att specificera -R-parametern är mycket viktigt så det kommer att återskapa recovery.conf, medan -S ska specificera vilket platsnamn som ska användas när standbynoden återskapas.

Slutsats

Att implementera replikeringsplatserna i PostgreSQL är enkelt men det finns vissa varningar som du måste komma ihåg. När du distribuerar med ClusterControl måste du uppdatera vissa inställningar under failover eller slav-ombyggnader.


  1. Hur man ställer in en fjärransluten MySQL-anslutning

  2. Hur man kontrollerar status för PostgreSQL-servern Mac OS X

  3. Hur man distribuerar MariaDB Cluster 10.5 för hög tillgänglighet

  4. Hur man använder GROUP BY-sats i SQL