Hvilke målinger for din PostgreSQL-implementering skal du overvåge? Denne serie af blogindlæg har til formål at give et minimalt startsæt af væsentlige overvågningshandlinger, som du bør implementere for at sikre sundheden og stabiliteten af dine Postgres-servere.
Dette er anden del af en blog-serie og dækker parametre på databaseniveau. Den første er dækket af parametre på klyngeniveau.
Del 2:Databaseniveau
I denne del ser vi på metrics og information, der bør overvåges for hver vigtig database, du bruger.
De fleste af de SQL-forespørgsler, der er anført nedenfor, bør køres, mens de er forbundet til den pågældende database.
1. Forbundne klienter
Forbundne klienter optager OS og systemressourcer. Postgres har en proces-per-klient-arkitektur, og for mange klienter kan sænke forespørgselssvartider for alle. Overvej at bruge PgBouncer orpgpool til at reducere antallet af forbindelser, som Postgres-serveren skal servicere.
Hold øje med ændringer i baseline efter applikationsopdateringer og stigninger i forbindelsen på grund af øget trafik.
Handling:Overvåg det maksimale antal tilsluttede klienter hver dag/uge, undersøg trendændringer.
Sådan:
-- returns the number of clients connected for each database
SELECT datname, count(*)
FROM pg_stat_activity
GROUP BY datname;
2. Størrelse
Den faktiske diskstørrelse, der bruges af databasen, skal overvåges. I de fleste tilfælde bliver databasestørrelsen ved med at vokse, så det er vækstraten, der er mere interessant. Igen, vær på vagt over for øget vækstrate efter nye applikationsudgivelser.
Handling:Overvåg væksten i databasens størrelse i løbet af hver uge/måned, undersøg tendenser, re-provision.
Sådan:
-- returns the size for each database
SELECT datname, pg_size_pretty(pg_database_size(datname))
FROM pg_database;
3. Bordsvulst på tværs af alle borde
På grund af Postgres' MVCC-arkitektur ligger ældre versioner af rækker rundt i de fysiske datafiler for hver tabel og kaldes bloat . Operationen for at fjerne forældede rækkeversioner kaldes vakuum . Postgres kører en baggrundsproces kaldet autovacuum , som opfanger kandidattabeller (baseret på konfigurerbare parametre) og støvsuger dem for dig.
Bloat sænker borddriften og spilder diskplads og kan løbe væk selv med autovakuum. Overvågning af bloat, som et absolut antal bytes samt en procentdel (af døde data i forhold til samlede data), er påkrævet. Dette kan gøres på databaseniveau som en total på tværs af alle tabeller, med mulighed for at bore ned i de "mest oppustede tabeller".
Handling:Overvåg kontinuerligt den samlede bloat som bytes og procent, advars, hvis værdierne overstiger en fastsat tærskel.
Sådan:
Brug check_postgres orpgmetrics for at få bloat estimater. Se wikien for mere information.
4. Indeksbloat på tværs af alle indekser
Opsvulmede indekser kan sænke inserts og reducere opslagsydelsen. Overvåg antallet af indekser som både en absolut værdi (antal bytes) og som en procentdel. Indekser skal genopbygges, når de bliver for oppustede.
Handling:Overvåg kontinuerligt den samlede bloat som bytes og procent, advars, hvis værdierne overstiger en fastsat tærskel.
Sådan:
Brug check_postgres orpgmetrics for at få bloat estimater. Se wikien for mere information.
5. Langvarige transaktioner
Transaktioner, der er åbne for længe, er ikke gode nyheder for PostgreSQL. Langvarige transaktioner kan forårsage tilbageholdelse af WAL-filer, kan hænge på låse og forhindre vakuum. Applikationer bør designes til at holde transaktionsvarigheden så lav som muligt.
En backend, der kører en langvarig transaktion, kan aflives med pg_cancel_backend() og pg_terminate_backend() funktioner.
Handling:Overvåg kontinuerligt antallet af transaktioner, der har kørt i mere end en fastsat varighed, advars, hvis værdierne overstiger en fastsat tærskel.
Sådan:
-- returns the count of transactions that have been running for more than a day
SELECT count(*)
FROM pg_stat_activity
WHERE xact_start < now() - '24 hours'::interval;
6. dødvande
I PostgreSQL placerer backends implicit låse på rækker og tabeller, mens det går ud på at udføre forespørgsler, der ændrer rækker. Forespørgsler kan også placere eksplicitte låse (som VÆLG .. TIL OPDATERING ). Ligesom i flertrådsprogrammering kan to transaktioner, der placerer låse, enten implicit eller eksplicit, i modsat rækkefølge resultere i en dødvande.
PostgreSQL vil opdage deadlocks og vil rulle en af de involverede transaktioner tilbage (Alle låse, som en transaktion har, frigives, når den er begået eller rulles tilbage). Detaljer vil blive logget i PostgreSQL-logningsdestinationen.
Applikationer bør udformes, så de undgår muligheden for dødvande. De kan også vælge at prøve en transaktion igen i tilfælde af dødvande.
Handling:Overvåg antallet af dødvande over hver dag/uge, redesign applikationen for at reducere antallet, undersøg ændringer.
Sådan:
Forekomster af deadlocks, sammen med yderligere oplysninger, logges i PostgreSQL-logfilen. Brug pgmetrics, pgbadger eller andre PostgreSQL-specifikke logbehandlingsværktøjer til at udtrække disse oplysninger.
7. Ældste støvsuger
Regelmæssig støvsugning af borde, enten med autovakuum, eller med planlagte job, eller manuelt er et must for at holde borddriften hurtig. Støvsugere kan dog fejle af forskellige årsager, herunder langvarige transaktioner, inaktive replikationsslots osv.
Da regelmæssig støvsugning af borde er ret vigtig i Postgres-verdenen, er det bedst regelmæssigt at tjekke, om alle borde er blevet støvsuget mindst én gang i et fastsat interval.
Og selvom de har en tendens til at være ude af syne og ude af sind, bør systemkatalogerne også støvsuges.
Handling:Kontroller løbende, om et bord ikke er blevet støvsuget inden for det seneste indstillede antal timer/dage, advar evt.
Sådan:
-- returns the top 5 tables vacuumed least recently
SELECT schemaname || '.' || relname, now()-last_vacuum
FROM pg_stat_all_tables
ORDER BY last_vacuum ASC NULLS LAST LIMIT 5;
-- returns all tables that have not been vacuumed in the last 7 days
SELECT schemaname || '.' || relname, now()-last_vacuum
FROM pg_stat_all_tables
WHERE last_vacuum < now() - '7 days'::interval;
8. Ældste Analyse
For at udføre dine SELECT-forespørgsler skal du bruge forespørgselsplanlæggeren udarbejder enudførelsesplan der beskriver hvilke indekser og tabeller der skal læses, og hvordan. For at komme med en effektiv eksekveringsplan skal planlæggeren have statistik over fordelingen af værdier, størrelser af tuples og så videre. Sådanne statistiske oplysninger om dataene i en tabel indsamles og vedligeholdes ved analyse operationer. Tabeller med opdateret statistik resulterer i hurtigere forespørgsler og mindre I/O.
Autovakuumprocessen nævnt ovenfor kører typisk også ANALYSE på bordet støvsuger den for at holde denne information opdateret. Dette alene giver dog muligvis ikke tilstrækkelig analysedækning for dine tabeller. Du vil gerne supplere ved at køre ANALYSE som planlagte job eller efter betydelige tabelmutationer.
Af hensyn til forespørgselsydelsen er det bedst løbende at kontrollere, om alle tabeller er blevet analyseret mindst én gang i et fastsat interval.
Handling:Kontroller løbende, om en tabel ikke er blevet analyseret inden for det seneste indstillede antal timer/dage, advar evt.
Sådan:
-- returns the top 5 tables analyzed least recently
SELECT schemaname || '.' || relname, now()-last_analyze
FROM pg_stat_all_tables
ORDER BY last_analyze ASC NULLS LAST LIMIT 5;
-- returns all tables that have not been analyzed in the last 7 days
SELECT schemaname || '.' || relname, now()-last_analyze
FROM pg_stat_all_tables
WHERE last_analyze < now() - '7 days'::interval;
Indsamling af disse metrics
Sektionerne ovenfor giver SQL-sætninger til at udtrække de nødvendige metrics fra en kørende Postgres-server. Hvis du hellere ikke vil skrive scripts selv, så tjek open source-værktøjet pgmetrics. Den kan indsamle metrics ovenfor og mere og rapportere dem i tekst- og JSON-formater.
Du kan sende pgmetrics-rapporterne direkte til vores kommercielle tilbud, pgDash, som gemmer og behandler disse rapporter for at vise grafer og udføre advarsler.
Næste op
Den næste del i denne serie vil dække tabel-niveau, indeks-niveau og system-niveau metrics. Følg med!