sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL:Sex inte så lätta stycken

PostgreSQL kommer med en utmärkt uppsättning funktioner, oöverträffade i RDBMS-utrymmet med öppen källkod. Det är mestadels lätt att lära sig och använda, särskilt för applikationsutvecklare. Men vissa delar är, ja, helt enkelt inte lätta. De kräver arbete för att ställa in och bli rätt, och är vanligtvis också verksamhetskritiska.

Anslutningshantering

PostgreSQL lanserar en ny process, kallad en backend-process , för att hantera varje anslutning. Detta till skillnad från moderna, eventloop/threadpool-baserade anslutningshanteringsarkitekturer som finns i andra jämförbara serverprogramvara. Att skapa en fullständig process tar mer tid och resurser och visar på ökade frågefördröjningar i applikationer där anslutningar öppnas och stängs i hög takt.

I de flesta distributioner krävs pooling av anslutningar på någon nivå. På en applikationsnivå kan detta vara att använda dina programmeringsspråk/biblioteksfunktioner. Till exempel kan sql/DB.SetMaxIdleConn användas för att öka återanvändningen av anslutningar från en enskild Go-applikation.

Ofta måste du dock använda en anslutningspoolning eller lastbalanseringslösning från tredje part. Anslutningspoolare upprätthåller en pool av lediga anslutningar till uppströms Postgres-servern, som tilldelas och proxias till inkommande klientanslutningar. De analyserar vanligtvis SQL som skickas av klienter för att känna igen transaktionsgränser och datamodifierande DML:er för att implementera funktioner som anslutningspoolning på transaktionsnivå och läsrepliker.

PgBouncer är en populär, lätt, enkelbinär anslutningspoolare och körs ofta tillsammans med PostgreSQL i samma system.

PgPool är mer mångsidig än PgBouncer. Den kan också göra lastbalansering och replikering till exempel.

Connection pooling ger dock sin egen uppsättning huvudvärk. För det första är det ytterligare en rörlig del som har underhållits i din installation. Att ställa in autentisering är också svårt om du har klienter som använder olika inloggningsuppgifter eller autentiseringsmekanismer. Vissa funktioner på anslutningsnivå som LISTEN/NOTIFY, förberedda uttalanden, tillfälliga tabeller och liknande kan kräva extra konfiguration eller ändringar på klientsidan för att fungera.

Noll uppgraderingar av driftstopp

Uppgradering av PostgreSQL mellan mindre versioner (13.x -> 13.y) innebär installation av det nya paketet och omstart av serverprocessen. Även om omstart av serverprocessen nödvändigtvis kommer att störa alla anslutna klienter, är det fortfarande en rimlig fråga, med tanke på att driftstoppet är bunden till varaktigheten av en omstart av tjänsten.

Att uppgradera mellan större (12.x -> 13.y) versioner är dock en mycket större affär. Vanligtvis gäller att ju mer data det finns, desto mer smärtsam är processen.

Den enklaste metoden, som bara fungerar för små mängder data (säg tiotals GB), är att dumpa data från den gamla versionen och återställa den till en server med ny version. Ett annat alternativ är att använda pg_upgrade, som kräver en orkestrerad dans involverar binärer av båda versionerna av Postgres.

I båda fallen skulle databaserna vara nere under en avsevärd tid.

Helst bör det vara möjligt att replikera till en ny versionsserver och marknadsföra den nya versionsservern som primär. Det är dock inte möjligt att göra strömmande replikering till en standby-server med en annan huvudversion. Logisk replikering, även om den ser väl lämpad för jobbet, har vissa saker som måste lösas för att säkerställa fullständig replikering.

De flesta HA-lösningar för Postgres är beroende av strömmande replikering, och därför kan du inte uppgradera noder i ett kluster en i taget.

Nuvarande toppmoderna skulle vara att använda logisk replikering, samtidigt som man undviker begränsningarna för logisk replikering, och eventuellt involverar begränsningsfunktioner som program kan använda (som DDL) under uppgraderingsfasen.

Hög tillgänglighet

PostgreSQL kommer med alla lågnivåfunktioner som krävs för att bygga en HA-lösning:replikering med återkoppling, kaskadreplikering, synkronreplikering, standby, hot standby, standby promotion och så vidare. Det ger dock inte faktiskt en HA-lösning direkt. Det finns inga ramverk eller verktyg för att övervaka tillstånd och automatisk övergång till standby. Det finns ingen idé om ett HA-kluster med flera noder.

Du måste konfigurera och köra en tredjepartslösning för att skapa Postgres-distributioner med hög tillgänglighet. Aktuella favoriter är pg_auto_failover och Patroni. Medan Patroni förlitar sig på en befintlig mycket tillgänglig konfigurationsbutik som ZooKeeper eller etcd, kan pg_auto_failover klara sig utan en sådan.

Att utvärdera, distribuera och testa en av dessa i produktionen tar tid och ansträngning. Spelböcker för övervakning, varningar och operationer måste ställas in och underhållas.

Bloat Management

PostgreSQL:s MVCC-arkitektur innebär att ingen data någonsin skrivs över – modifiering av en rad resulterar bara i att en ny version av raden skrivs ut till disk. Att ta bort en rad innebär bara att man registrerar att raden är osynlig för framtida transaktioner. När en radversion är otillgänglig från pågående eller framtida transaktioner är den inte längre till någon nytta och kallas "bloat". Processen för att samla in denna svällning kallas "vakuum".

Bloat är osynligt för applikationer och blir enbart DBA:s huvudvärk. För uppdateringstunga tabeller är övervakning och hantering av bloat en icke-trivial fråga. Autovakuumprocessen hjälper mycket, men dess tröskelvärden kan behöva justeras till en global eller per- bordsnivå för att säkerställa att bordsstorlekarna inte blir ohanterligt stora.

Index påverkas också av uppblåsthet, och autovakuum hjälper inte här. Radering av rader och uppdatering av indexerade kolumner leder till döda poster i index. Uppdateringstunga arbetsbelastningar med uppdateringar till indexerade kolumner kan leda till ständigt växande och ineffektiva index. Det finns ingen motsvarighet till vakuum för index. Den enda lösningen är att bygga om hela indexet med REINDEX eller använda VACUUM FULL på bordet.

Förutom ett enda värde per tabell (pg_stat_all_tables.n_dead_tup), erbjuder Postgres ingenting i vägen för att uppskatta svulsten i en tabell, och ingenting alls för index. Det mest praktiska sättet är fortfarande att köra en läskig fråga från check_postgres.

pgmetrics inkorporerar frågan från check_postgres och kan producera JSON- och CSV-formatutdata som inkluderar storlek och uppsvälld information för alla tabeller och index; som kan matas in i övervaknings- eller automationsverktyg.

pg_repack är ett populärt alternativ till VACUUM FULL – det kan göra samma jobb men utan lås. Om du tvingas göra VAKUUM FULL regelbundet är det ett verktyg som måste undersökas.

zheap är den nya lagringsmotorn för Postgres som har varit under utveckling i flera år, som lovar att minska uppblåsthet genom uppdateringar på plats.

Frågeplanshantering

Core PostgreSQL erbjuder bara två rudimentära verktyg i detta utrymme:

  • pg_stat_statements tillägg för frågeanalys – detta ger totala och medelvärden för frågeplanering och exekveringstider, disk- och minnesanvändning
  • auto_explain tillägg, som kan skriva ut exekveringsplaner för frågor till Postgres-loggdestinationen

Medan statistiken som tillhandahålls av pg_stat_statements bara räcker för att klara sig, med auto_explain att tvinga in planer i loggfiler och sedan extrahera dem inte mer än ett hack, särskilt jämfört med kommersiella konkurrenter till Postgres, som erbjuder planhistorik, baslinje och hanteringsfunktioner.

Den aktuella tekniken med Postgres är att bryta loggfilen för förfrågningsplaner och lagra dem någon annanstans. Men det kanske mest handikappande problemet är att inte kunna associera frågeplanen med motsvarande analys från pg_stat_statements. Sättet pgDash gör detta på är att analysera både SQL-frågetexterna från pg_stat_statements och auto_explain-utdata, justera för manglingen som görs av pg_stat_statements och försöka matcha de två. Det kräver en komplett PostgreSQL-dialekt SQL-parser.

Baselining, inställning av policyer för planval, etc. är helt enkelt inte möjliga i kärnan i PostgreSQL för närvarande.

Det finns några tillägg där ute som i grunden är förbättrade versioner av pg_stat_statements, men de extra stegen som är involverade i att använda en tredjepartstillägg gör det till en utmaning för de flesta, särskilt om de använder en hanterad Postgres-leverantör.

Inställning

PostgreSQL har en uppsjö av inställningsalternativ, från inställningen under-konfigurerad-by-defaultshared_buffers. Vissa är lätta att förstå och ställa in, som antalet parallella arbetare för olika operationer (max_arbetarprocesser, max_parallell_* etc). Andra områden lite obskyrt (wal_compression, random_page_cost etc) men generellt fördelaktiga. De mest irriterande är dock de som behöver kvantifierbar information om arbetsbelastningen.

Till exempel om work_mem är för låg, kan frågor använda temporära diskfiler; om det är för högt och det finns tillräckligt många samtidiga frågor, kan Postgres backendprocesser vara OOM-dödade. Så hur tar du reda på vilket nummer du ska ställa in det på?

Praktiskt taget, särskilt med OLTP-arbetsbelastningar och webbapplikationsarbetsbelastningar, är det omöjligt att förutsäga vad det maximala minnesbehovet för frågor skulle vara. Det bästa är att ställa in det till ett rimligt värde och sedan övervaka frågor för att se om någon av dem kunde ha haft nytta av ett högre värde på work_mem.

Och hur gör man det? Du måste skaffa tillägget auto_explain för att logga exekveringsplanerna för varje fråga, extrahera dem från Postgres loggfiler, granska varje frågeplan för att se om den använder diskbaserade externa sammanslagningar eller en bitmappshögavsökning med förlusthögblock.

Inte omöjligt, bara svårt.


  1. Hur kontrollerar man ett saknat nummer från en serie nummer?

  2. Hur man ansluter till SQL Server med Windows-autentisering från Node.JS med hjälp av mssql-modulen

  3. MariaDB JSON_TABLE() Förklarad

  4. Hur man visar sorteringen av en kolumn i SQL Server (T-SQL)