sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL-replicatieslots gebruiken

Wat zijn replicatieslots?

In de tijd dat 'replicatieslots' nog niet waren geïntroduceerd, was het beheren van de WAL-segmenten een uitdaging. Bij standaard streaming-replicatie heeft de master geen kennis van de slave-status. Neem het voorbeeld van een master die een grote transactie uitvoert, terwijl een standby-node een paar uur in onderhoudsmodus is (zoals het upgraden van de systeempakketten, het aanpassen van de netwerkbeveiliging, hardware-upgrade, enz.). Op een gegeven moment verwijdert de master zijn transactielogboek (WAL-segmenten) als het controlepunt passeert. Als de slave eenmaal uit onderhoud is, heeft hij mogelijk een enorme slave-lag en moet hij de master inhalen. Uiteindelijk krijgt de slaaf een fataal probleem zoals hieronder:

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

De typische benadering is om in uw postgresql.conf een WAL-archiveringsscript te specificeren dat WAL-bestanden naar een of meer langetermijnarchieflocaties zal kopiëren. Als u geen standbys of andere streaming-replicatieclients hebt, kan de server het WAL-bestand in principe weggooien zodra het archiefscript is voltooid of OK reageert. Maar je hebt nog steeds enkele recente WAL-bestanden nodig voor crashherstel (gegevens van recente WAL-bestanden worden opnieuw afgespeeld tijdens crashherstel. de primaire voor een WAL-bestand dat de primaire niet meer heeft, dan mislukt de replicatie.

Dit probleem is verholpen in PostgreSQL 9.4 via "Replicatieslots".

Als er geen replicatieslots worden gebruikt, is een veelgebruikte manier om het risico op mislukte replicatie te verminderen, de wal_keep_segments hoog genoeg in te stellen, zodat de eventueel benodigde WAL-bestanden niet worden geroteerd of gerecycled. Het nadeel van deze aanpak is dat het moeilijk is om te bepalen welke waarde het beste is voor uw opstelling. U heeft geen dagelijks onderhoud nodig of u hoeft geen grote stapel WAL-bestanden te bewaren die uw schijfopslag opslokken. Hoewel dit werkt, is het geen ideale oplossing, omdat het riskeren van schijfruimte op de master ertoe kan leiden dat inkomende transacties mislukken.

Alternatieve benaderingen om geen replicatieslots te gebruiken, is om PostgreSQL te configureren met continue archivering en een herstelopdracht te geven om de replica toegang tot het archief te geven. Om WAL-opbouw op de primaire te voorkomen, kunt u een apart volume of opslagapparaat gebruiken voor de WAL-bestanden, bijvoorbeeld SAN of NFS. Een ander ding is met synchrone replicatie, omdat het vereist dat de primaire knooppunten moeten wachten op standby-knooppunten om de transactie door te voeren. Dit betekent dat het ervoor zorgt dat WAL-bestanden zijn toegepast op de standby-knooppunten. Maar toch, het is het beste dat u archiveringscommando's van de primaire geeft, zodat zodra WAL's in de primaire zijn gerecycled, u er zeker van kunt zijn dat u WAL-back-ups hebt voor het geval ze moeten worden hersteld. Hoewel in sommige situaties synchrone replicatie geen ideale oplossing is, omdat het gepaard gaat met enige prestatieoverhead in vergelijking met asynchrone replicatie.

Soorten replicatieslots

Er zijn twee soorten replicatieslots. Dit zijn:

Fysieke replicatieslots 

Kan worden gebruikt voor standaard streaming-replicatie. Zij zorgen ervoor dat gegevens niet te vroeg worden hergebruikt.

Logische replicatieslots

Logische replicatie doet hetzelfde als fysieke replicatieslots en wordt gebruikt voor logische replicatie. Ze worden echter gebruikt voor logische decodering. Het idee achter logische decodering is om gebruikers de kans te geven om aan het transactielogboek te koppelen en het te decoderen met een plug-in. Het maakt het mogelijk om wijzigingen in de database en dus in het transactielogboek in elk formaat en voor elk doel te extraheren.

In deze blog zullen we fysieke replicatieslots gebruiken en hoe we dit kunnen bereiken met ClusterControl.

Voor- en nadelen van het gebruik van replicatieslots

Replicatiesleuven zijn zeker nuttig als ze eenmaal zijn ingeschakeld. 'Replicatieslots' zijn standaard niet ingeschakeld en moeten handmatig worden ingesteld. Een van de voordelen van het gebruik van replicatieslots zijn

  • Zorgt ervoor dat de master voldoende WAL-segmenten behoudt zodat alle replica's ze kunnen ontvangen
  • Voorkomt dat de master rijen verwijdert die herstelconflicten op de replica's kunnen veroorzaken
  • Een master kan het transactielogboek pas recyclen als het door alle replica's is verbruikt. Het voordeel hiervan is dat een slaaf nooit zo veel achter kan raken dat een hersynchronisatie nodig is.

Replicatieslots hebben ook enkele kanttekeningen.

  • Een weesreplicatieslot kan onbegrensde schijfgroei veroorzaken door opgestapelde WAL-bestanden van de master
  • Slaafknooppunten die langdurig worden onderhouden (zoals dagen of weken) en die zijn gekoppeld aan een replicatieslot, zullen een onbeperkte schijfgroei hebben als gevolg van opgestapelde WAL-bestanden van de master

Je kunt dit controleren door pg_replication_slots op te vragen om te bepalen welke slots niet worden gebruikt. We komen hier later op terug.

Replicatieslots gebruiken 

Zoals eerder vermeld, zijn er twee soorten replicatieslots. Voor deze blog gebruiken we fysieke replicatieslots voor streamingreplicatie.

Een replicatieslot maken

Een replicatie maken is eenvoudig. U moet hiervoor de bestaande functie pg_create_physical_replication_slot aanroepen en moet worden uitgevoerd en gemaakt in het hoofdknooppunt. De functie is eenvoudig,

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

bijv. Een replicatieslot maken met de naam slot1,

postgres=# SELECT pg_create_physical_replication_slot('slot1');

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

pg_create_physical_replication_slot | (slot1,)

De namen van de replicatieslots en de onderliggende configuratie zijn alleen systeembreed en niet clusterbreed. Als u bijvoorbeeld nodeA (huidige master) en stand-by nodes nodeB en nodeC hebt en het slot op een masternodeA maakt, namelijk "slot1", dan zijn de gegevens niet beschikbaar voor nodeB en nodeC. Daarom moet u, wanneer een failover/omschakeling op het punt staat te gebeuren, de door u gemaakte slots opnieuw maken.

Een replicatieslot laten vallen

Ongebruikte replicatieslots moeten worden verwijderd of verwijderd. Zoals eerder vermeld, wanneer er zwevende replicatieslots zijn of slots die niet zijn toegewezen aan client- of standby-knooppunten, kan dit leiden tot grenzeloze schijfruimteproblemen als ze niet worden verwijderd. Het is dus erg belangrijk dat deze moeten worden verwijderd als ze niet meer worden gebruikt. Om het te laten vallen, roept u eenvoudig pg_drop_replication_slot op. Deze functie heeft de volgende definitie:

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

Het laten vallen is eenvoudig:

maximus_db=# select pg_drop_replication_slot('slot2');

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

pg_drop_replication_slot |

Uw PostgreSQL-replicatieslots bewaken

Het bewaken van uw replicatieslots is iets dat u niet wilt missen. Verzamel gewoon de informatie van view pg_replication_slots in het primaire/masterknooppunt, zoals hieronder:

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 |

Het bovenstaande resultaat laat zien dat de main_slot is ingenomen, maar niet main_slot2.

Een ander ding dat je kunt doen, is controleren hoeveel achterstand je hebt op de slots. Om dit te bereiken, kunt u eenvoudig de query gebruiken op basis van het onderstaande voorbeeldresultaat:

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

Maar redo_lsn is niet aanwezig in 9.6, zal redo_location gebruiken, dus in 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

Vereisten voor systeemvariabelen

Het implementeren van replicatieslots vereist handmatige instelling. Er zijn variabelen waarmee u rekening moet houden die wijzigingen vereisen en die in uw postgresql.conf moeten worden gespecificeerd. Zie hieronder:

  • max_replication_slots – Indien ingesteld op 0, betekent dit dat replicatieslots volledig zijn uitgeschakeld. Als u PostgreSQL <10 versies gebruikt, moet deze sleuf anders worden opgegeven dan 0 (standaard). Sinds PostgreSQL 10 is de standaardwaarde 10. Deze variabele specificeert het maximum aantal replicatieslots. Als u deze instelt op een lagere waarde dan het aantal momenteel bestaande replicatieslots, kan de server niet starten.
  • wal_level – moet minimaal replica of hoger zijn (replica is standaard). Het instellen van hot_standby of archive wordt toegewezen aan replica. Voor een fysieke replicatiesleuf is replica voldoende. Voor logische replicatieslots heeft logisch de voorkeur.
  • max_wal_senders – standaard ingesteld op 10, 0 in versie 9.6, wat betekent dat replicatie is uitgeschakeld. We raden u aan dit minimaal op 16 in te stellen, vooral als u met ClusterControl werkt.
  • hot_standby – in versies <10 moet u dit instellen op aan, wat standaard is uitgeschakeld. Dit is belangrijk voor stand-by-knooppunten, wat betekent dat u verbinding kunt maken en query's kunt uitvoeren tijdens herstel of in de stand-bymodus.
  • primary_slot_name:deze variabele wordt ingesteld via recovery.conf op het standby-knooppunt. Dit is het slot dat door de ontvanger of het standby-knooppunt moet worden gebruikt wanneer verbinding wordt gemaakt met de afzender (of primaire/master).

Houd er rekening mee dat deze variabelen meestal een herstart van de databaseservice vereisen om nieuwe waarden opnieuw te laden.

Replicatieslots gebruiken in een ClusterControl PostgreSQL-omgeving

Laten we nu eens kijken hoe we fysieke replicatieslots kunnen gebruiken en deze kunnen implementeren in een Postgres-configuratie die wordt beheerd door ClusterControl.

Implementatie van PostgreSQL-databaseknooppunten

Laten we deze keer beginnen met het implementeren van een PostgreSQL-cluster met 3 knooppunten met behulp van ClusterControl en de versie van PostgreSQL 9.6.

ClusterControl implementeert knooppunten met de volgende systeemvariabelen die overeenkomstig zijn gedefinieerd op basis van hun standaardinstellingen of opgewaardeerde waarden. In:

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)

In versies PostgreSQL> 9.6 is de standaardwaarde van max_replication_slots 10 die standaard is ingeschakeld, maar niet in versies 9.6 of lager die standaard is uitgeschakeld. U moet max_replication_slots hoger dan 0 toewijzen. In dit voorbeeld stel ik max_replication_slots in op 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

en de service opnieuw gestart,

[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

De replicatieslots instellen voor primaire en standby-knooppunten

Er is geen optie in ClusterControl om dit te doen, dus u moet uw slots handmatig maken. In dit voorbeeld heb ik de slots in de primaire in host 192.168.30.100 gemaakt:

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)

Controleren wat we zojuist voor shows hebben gemaakt,

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 moeten we in de standby-knooppunten de recovery.conf bijwerken en de variabele primary_slot_name toevoegen en de application_name wijzigen, zodat het gemakkelijker is om de node te identificeren. Zo ziet het eruit in host 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'

Ook hetzelfde doen in host 192.168.30.120 maar de naam van de toepassing gewijzigd en de primary_slot_name ='slot2' ingesteld.

De gezondheid van de replicatiesleuf controleren:

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)

Wat heb je nog meer nodig?

Aangezien ClusterControl op dit moment geen replicatieslots ondersteunt, zijn er zaken waar u rekening mee moet houden. Wat zijn deze? Laten we in details treden.

Failover/Switchover-proces

Als een automatische failover of omschakeling via ClusterControl is geprobeerd, worden de slots van de primaire en op de standby-knooppunten niet behouden. U moet dit handmatig opnieuw maken, de variabelen controleren als ze correct zijn ingesteld en de recovery.conf dienovereenkomstig aanpassen.

Een slaaf herbouwen van een meester

Bij het opnieuw opbouwen van een slave, zal de recovery.conf niet behouden blijven. Dit betekent dat uw recovery.conf instellingen met de primary_slot_name zullen worden gewist. U moet dit opnieuw handmatig opgeven en de weergave pg_replication_slots controleren om te bepalen of slots correct worden gebruikt of verweesd blijven.

Als u het slave/standby-knooppunt van een master opnieuw wilt opbouwen, moet u misschien overwegen om de PGAPPNAME env-variabele op te geven, net zoals de onderstaande opdracht:

$ 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

Het specificeren van de -R param is erg belangrijk, dus het zal de recovery.conf opnieuw maken, terwijl -S zal specificeren welke slotnaam moet worden gebruikt bij het opnieuw opbouwen van het standby-knooppunt.

Conclusie

Het implementeren van de replicatieslots in PostgreSQL is eenvoudig, maar er zijn bepaalde kanttekeningen die u moet onthouden. Wanneer u implementeert met ClusterControl, moet u enkele instellingen bijwerken tijdens failover of slave-reconstructies.


  1. SQL Server, een benoemd exemplaar converteren naar een standaardexemplaar?

  2. MySQL-databases maken en onderhouden in cPanel

  3. SQL Server-replicatie instellen en configureren

  4. Hoe COALESCE() werkt in MariaDB