Een beetje zorg en verzorging van uw PostgreSQL-implementatie gaat een lange weg om de prestaties te garanderen, onaangename ontdekkingen te vermijden en betrouwbare voorspelbaarheid te creëren. Hier zijn 7 dingen die je in de gaten moet houden.
Table Bloat
PostgreSQL implementeert transacties met behulp van een techniek genaamd MVCC.MVCC is te lang en omvat een onderwerp om in detail te bespreken, maar er zijndrie dingen die je moet weet ervan:
- Als u een rij verwijdert, wordt deze alleen gemarkeerd als 'onzichtbaar' voor toekomstige transacties.
- Als u een rij bijwerkt, wordt er een nieuwe versie van de rij gemaakt. De oude versie is gemarkeerd als onzichtbaar voor toekomstige transacties en de nieuwe versie is gemarkeerd als zichtbaar.
- Soms moet iemand alle huidige transacties bekijken en zeggen:OK, de oudste transactie hier is #42, dus elke rijversie die onzichtbaar is voor #42 kan fysiek worden verwijderd zonder de consistentie van de gegevens in gevaar te brengen.
Dat is hoe MVCC (in wezen) werkt, en de implicatie is dat updates zullen vergroot de voetafdruk van uw fysieke databaseopslag en verwijderingen zullen niet verminder het. MVCC klinkt als een luie manier om dingen te doen, maar het is populair omdat het zowel consistentie als prestaties biedt.
De ongewenste, verouderde rijversies in een tabel worden bloat . genoemd (of deadrows ). Het proces dat een opgeblazen gevoel kan verwijderen, wordt vacuüm genoemd . PostgreSQL heeft een automatisch geactiveerd vacuümproces met instelbare drempels, autovacuüm genaamd, en natuurlijk het VACUUM-commando.
Over het algemeen kan bloat ook zoekopdrachten vertragen vanwege onnauwkeurige zichtbaarheidskaarten en verspilde schijf-I/O.
Daarom moet u regelmatig:
- controleer de hoeveelheid bloat in een database
- regelmatig stofzuigen
- controleer of er regelmatig gestofzuigd wordt voor alle tafels
Er zijn een paar SQL-query's om een schatting van de bloat per tabel te geven. De open source toolpgmetrics biedt schattingen van de bloat en de laatste looptijden van handmatig en automatisch vacuüm.
Indexbloat
Indexen kunnen ook opzwellen. Hoewel de interne structuur van indexen ondoorzichtig is voor de SQL-gebruiker en verschilt per indextype (Btree, hash, GIN, GIST, enz.), blijft het algemene idee dat wanneer rijen waarnaar door de index wordt verwezen worden verwijderd, de ruimte die wordt ingenomen door de gerelateerde informatie binnen de index wordt alleen logisch verwijderd en niet terug vrijgegeven aan het bestandssysteem. De logisch verwijderde ruimte kan later door de index opnieuw worden gebruikt.
Er zijn twee manieren om Postgres de fysieke grootte van een index te laten verkleinen:
- de VOLLEDIGE versie van het VACUUM-commando
- REINDEX
Index bloat moet worden gecontroleerd, zodat u op zijn minst op de hoogte bent van de hoeveelheid ongebruikte ruimte. In tabellen met een hoog rijverloop is het niet ongebruikelijk om regelmatig indexhersteltaken in te stellen.
Index-bloat kan ook worden verkregen door dezelfde zoekopdrachten als voorheen, en ook via pgmetrics.
Langlopende transacties
Transacties moeten zo kort mogelijk worden gehouden, vooral in een MVCC-systeem.
Stel je voor dat gisteren een transactie begon en er vlak daarna een vacuümrun was. Zolang deze transactie open is, zijn verdere vacuüms nutteloos, aangezien onze transactie per definitie alle rijen van alle tabellen moet zien zoals ze waren toen onze transactie gisteren begon. Zelfs als onze transactie alleen-lezen is, is dit nog steeds het geval.
Als gevolg hiervan zorgen langlopende transacties voor een opgeblazen gevoel. Ze houden ook vast aan systeembronnen, houden niet-opgegeven sloten vast en vergroten de kans op impasses.
De beste manier om langlopende transacties in de gaten te houden, is door een waarschuwing in te stellen voor het aantal transacties dat al langer dan een bepaalde duur loopt. U kunt dit ophalen uit de statistiekenweergavepg_stat_activity
, zoals zo:
-- number of transactions that have been open for
-- more than 1 hour
SELECT count(*) FROM pg_stat_activity WHERE xact_start < now()-'1 hour'::interval;
Replicatievertraging
Wanneer streaming-replicatie wordt gebruikt om alle wijzigingen van een primaire PostgreSQL-server naar een hot-standby-server (ook wel read-replica genoemd) te repliceren, is er gewoonlijk een kleine vertraging tussen het moment waarop rij-updates plaatsvinden op de primaire server en wanneer de wijzigingen zichtbaar zijn voor applicaties die zijn aangesloten op de standby .
Er zijn echter gevallen waarin deze vertraging kan toenemen:
- het standby-systeem kan de wijzigingen van het primaire systeem niet snel genoeg ontvangen en toepassen om het bij te houden, meestal vanwege een hoge belasting of onderbezetting
- een beschadigd netwerk of schijf
- conflicten opvragen
Een stand-by met een hoge of erger nog, toenemende replicatievertraging kan ertoe leiden dat vragen over de stand-by verouderde gegevens retourneren en een stand-by die niet geschikt is voor failover.
Als u een streaming-replicatie-configuratie hebt, is het bewaken van replicatievertragingen tussen elk primair-standby-paar erg belangrijk, en u wilt waarschuwingen instellen om te controleren of de replicatievertragingen meer dan een minuut bedragen, of welke drempel dan ook die zinvol is voor uw installatie.
Dit bericht bevat veel meer over het meten en bewaken van replicatievertraging van zowel primaire als stand-by.
Inactieve replicatieslots
Het gebruik van replicatieslots, geïntroduceerd in PostgreSQL 9.4, maakt streamingreplicatie robuuster en efficiënter. In wezen rapporteert de stand-by de voortgang van de replicatie aan de primaire, die deze informatie opslaat in de "replicatiesleuf".
Hierdoor weet de primaire nu te allen tijde hoe ver achter de standby staat. Hierdoor kan de primaire een voldoende achterstand van WAL-bestanden behouden (die nodig zijn om de replicatie te hervatten) wanneer de stand-by offline gaat. Dus wanneer de stand-by terugkeert, zelfs na een lange tijd, kan de primaire nog steeds garanderen dat de replicatie kan worden hervat.
Voorafgaand aan replicatieslots, kan de primaire oude WAL-bestanden opschonen, omdat hij niet wist of de standbys ze nodig hadden of niet. Als een WAL-bestand dat stand-by nodig is, wordt verwijderd, is er geen manier om de replicatie te hervatten; het moet helemaal opnieuw worden ingesteld.
Het gedrag van de primaire om WAL-bestanden voor onbepaalde tijd te bewaren, leidt echter tot een ander probleem. Als een stand-by is uitgeschakeld en het bijbehorende replicatieslot niet is verwijderd, blijven WAL-bestanden voor altijd bewaard. WAL-bestanden die om deze reden worden bewaard, vallen niet onder de limieten die zijn ingesteld door max_wal_size
en andere configuratie-opties.
Deze situatie blijft bestaan totdat WAL-bestanden de hele schijfruimte opslokken, zelfs zonder waarschuwing in de PostgreSQL-logbestanden.
Onnodig te zeggen dat inactieve replicatieslots moeten worden aangepakt wanneer ze worden gedetecteerd. Vind uw inactieve replicatieslots met:
SELECT slot_name FROM pg_replication_slots WHERE NOT active;
Status analyseren
ANALYSE wordt uitgevoerd op tabellen om statistische informatie over de inhoud van de tabel te verzamelen en bij te werken. Deze informatie wordt door de queryplanner gebruikt om het uitvoeringsplan voor elke SQL-query op te stellen. Actuele statistieken over de inhoud van de tabel resulteren in een beter uitvoeringsplan, wat weer resulteert in een snellere zoekopdracht.
De autovacuum-daemon voert meestal ANALYSE uit na VACUUM. Dit kan echter niet vaak genoeg zijn voor ANALYSE. Als de distributie van de gegevens in de tabel vaak verandert, zou u ANALYSE vaker moeten uitvoeren.
Doorgaans gedraagt ANALYSE zich redelijk goed - het hoeft alleen sloten te lezen, verbruikt niet te veel bronnen en wordt binnen een redelijke tijd voltooid. Het is veilig om het vaker wel dan niet te gebruiken.
Het is een goed idee om tabellen in de gaten te houden die al een tijdje niet zijn ANALYSEERD. Ontdek de laatste keer dat uw tabellen (automatisch) zijn geanalyseerd met de query:
SELECT schemaname || '.' || relname, last_analyze, last_autoanalyze
FROM pg_stat_user_tables;
Brongebruik
Het bewaken van de CPU-belasting, het geheugen en het schijfgebruik zorgt ervoor dat u voldoende capaciteit bij de hand hebt om te voldoen aan de groeiende behoeften van de toepassingen die uw database gebruiken.
PostgreSQL brengt één proces voort om één verbinding af te handelen. Hoewel dit tegenwoordig misschien niet de meest schaalbare architectuur is, draagt het wel veel bij aan de stabiliteit. Het maakt ook het gemiddelde van de OS-belasting zinvoller. Omdat PostgreSQLboxen gewoonlijk alleen PostgreSQL draaien, betekent een gemiddelde belasting van bijvoorbeeld 3 meestal dat er 3 verbindingen wachten op het beschikbaar komen van CPU-kernen, zodat ze kunnen worden gepland. Door uw maximale belastinggemiddelde tijdens een typische dag of week te controleren, kunt u een schatting geven van hoe over- of ondergeprovisioneerd uw box is op het CPU-front.
Geheugen en vrije schijfruimte zijn natuurlijk standaard zaken om in de gaten te houden. Meer verbindingen en langer lopende transacties stellen hogere eisen aan het geheugen. En denk er bij het bewaken van de vrije schijfruimte aan deze per tabelruimte bij te houden.