Att hantera databaser är ingen liten uppgift och kan lätt vara frustrerande utan att veta vad som händer under täcket. Oavsett om man försöker ta reda på om nya index är användbara, transaktionen räknas på en databas vid en viss tidpunkt eller vem som är ansluten till databasen vid en given tidpunkt, data som gör att administratörerna verkligen vet hur deras databaser presterar är kung. Lyckligtvis, med PostgreSQL, är denna data för allt detta tillgänglig i PostgreSQL-systemkatalogen.
PostgreSQL System Catalog är ett schema med tabeller och vyer som innehåller metadata om alla andra objekt i databasen och mer. Med den kan vi upptäcka när olika operationer inträffar, hur tabeller eller index nås, och även om databassystemet läser information från minnet eller behöver hämta data från disken.
Här kommer vi att gå igenom en översikt över systemkatalogen och belysa hur man läser den och hur man hämtar användbar information från den. En del av metadata är okomplicerad, och andra delar kräver lite sammanfattning för att generera verklig användbar information. Hursomhelst, PostgreSQL ger oss en fantastisk plattform för att bygga all information vi behöver om själva databasen.
PostgreSQL-katalogen
PostgreSQL lagrar metadatainformationen om databasen och klustret i schemat 'pg_catalog'. Denna information används delvis av PostgreSQL själv för att hålla reda på saker själv, men den presenteras också så att externa personer/processer också kan förstå databasernas insida.
PostgreSQL-katalogen har en ganska solid regel:Titta, rör inte. Medan PostgreSQL lagrar all denna information i tabeller som vilken annan applikation som helst, hanteras data i tabellerna helt av PostgreSQL själv, och bör inte ändras om det inte är en absolut nödsituation, och även då en ombyggnad är sannolikt i sin ordning efteråt.
Vi kommer att gå igenom några användbara katalogtabeller, hur man läser data och smarta saker vi kan göra med själva data. Det finns en hel del tabeller i katalogen som vi inte kommer att gå igenom, men all information för dessa olika tabeller finns i PostgreSQL:s officiella dokumentation.
Metadata för hela systemet
En stor del av tabellerna vi kan fråga i katalogen är "systemwide" tabeller, där det inte spelar någon roll vilken databas vi är anslutna till, data representerar hela klustret, ingen enskild databas.
Databasinformation
Allmän databasinformation lagras i pg_database och statistik lagras i pg_stat_database.
pg_database:
postgres=# SELECT oid,* FROM pg_database WHERE datname = 'severalnines';
-[ RECORD 1 ]-+-------------
oid | 16396
datname | severalnines
datdba | 10
encoding | 6
datcollate | en_US.UTF-8
datctype | en_US.UTF-8
datistemplate | f
datallowconn | t
datconnlimit | -1
datlastsysoid | 13804
datfrozenxid | 548
datminmxid | 1
dattablespace | 1663
datacl |
Tabellen pg_database innehåller en rad för varje databas i klustret, inklusive de tre som kommer ut ur lådan (postgres, template0 och template1). Den här raden innehåller information om kodning, anslutningsgräns och andra grundläggande metadata.
Kolumner av intresse:
oid - Objektidentifieraren, som inte visas i en frågeutdata om den inte refereras direkt. Detta nummer kommer att matcha en katalog i klustrets datakatalog
datname - Namnet på databasen.
datdba - Databasens ägare, oid referenser pg_authid .oid.
kodning - Teckenkodningen för denna databas, pg_encoding_to_char() kommer att konverteras till ett läsbart namn.
datconnlimit - Det maximala antalet samtidiga anslutningar som tillåts i databasen.
dattablespace - Den standardtabellutrymme för denna databas, refererar till pg_tablespace.oid.
pg_stat_database:
postgres=# SELECT * FROM pg_stat_database WHERE datname = 'severalnines';
-[ RECORD 1 ]--+------------------------------
datid | 13805
datname | postgres
numbackends | 2
xact_commit | 477460
xact_rollback | 13
blks_read | 417
blks_hit | 16488702
tup_returned | 252376522
tup_fetched | 2637123
tup_inserted | 114
tup_updated | 3
tup_deleted | 1
conflicts | 0
temp_files | 0
temp_bytes | 0
deadlocks | 0
blk_read_time | 0
blk_write_time | 0
stats_reset | 2018-02-04 19:52:39.129052+00
Den här statistiktabellen är där vi får intressanta och användbara data. Varje rad i den här tabellen innehåller livedata för varje databas och kan exporteras regelbundet för att spåras över tid om man vill övervaka ändringar.
Transaktioner
Transaktionsinformation finns i kolumnerna xact_commit och xact_rollback, som innehåller antalet transaktioner som databasen har genomfört respektive återställt. Detta kommer att hjälpa till att visa hur aktiv en databas är, samt upptäcka möjliga fel med program som kan ha fel / rulla tillbaka i en alarmerande takt.
Disk- och minnesåtkomst
Information om huruvida data hämtas från disk eller minne lagras i kolumnerna blks_read och blks_hit. Blks_read visar antalet block som denna databas läste från disk, medan blks_hit visar antalet block som hittades i PostgreSQL:s buffertcache (representerad av shared_buffers-parametern). Eftersom RAM är mycket snabbare än disk skulle vi helst se blks_hit konsekvent högre än blks_read, och om inte kan vi omvärdera vårt tillgängliga minne.
Tuples
De följande kolumnerna handlar om tupler. Tup_returned är antalet rader som returneras i databasen, vilket är antalet rader som läses av sekventiella skanningar om från en tabell, eller antalet indexposter som returneras från ett index”. Tup_fetched är antalet rader som hämtats i databasen, vilket betyder att de var ett resultat av bitmappssökningar, vilket är antalet tabellrader som hämtas av bitmappssökningar om från en tabell, eller tabellrader som hämtas av enkla indexskanningar om ett index används.
Vi har också tup_inserted, tup_updated och tup_deleted, som representerar antalet tupler som infogats, uppdaterats och tagits bort i denna databas respektive. Detta hjälper till att förstå hur data kommer in, ändras och lämnar databasen. Eftersom uppdaterade och raderade tuplar resulterar i döda rader, skulle höga värden i dessa kolumner antyda att autovakuumoperationer justeras för att möta behoven för databasaktiviteten.
Konflikter
Om databasen i fråga är en standby-server kommer kolumnkonflikterna till nytta som ett sätt att spåra hur många frågor som avbröts på grund av konflikter med att standby-läget är i "återställningsläge". Om det inte är ett standby-kluster kan denna kolumn ignoreras.
Tillfälliga filer/data
Ibland kommer frågor att behöva skriva till temporära filer. Detta kan hända när mängden work_mem som allokerats till anslutningen har använts och behöver fortsätta en sorteringsoperation på disken snarare än i minnet. Kolumnen temp_files spårar antalet av dessa filer som skapades, och temp_bytes spårar den totala storleken på alla temporära filer som används. Denna data kan hjälpa till att informera work_mem tuning, eller till och med hitta frågor som kan behöva skriva om om den tillfälliga filstorleken är för stor.
Dödläge
Deadlocks-kolumnen spårar hur många gånger ett dödläge inträffar. Eftersom ett dödläge kan orsaka fel för frågor som annars inte skulle ha fel, är det bra att spåra detta och se till att applikationer inte trampar varandras fötter.
Läs- och skrivtider
Kolumnerna blk_read_time och blk_write_time spårar det totala antalet millisekunder som backends i databasen spenderar på att läsa och skriva data, vilket kan vara till hjälp om man försöker jämföra/förbättra läs-/skrivhastigheten på disken
Statistik återställd
Den här kolumnen, stats_reset, visar helt enkelt en tidsstämpel (med tidszon) för senaste gången statistiken som nämns i den här raden har återställts. Ett nollvärde betyder att de inte har återställts sedan starten, eller till och med en krasch av databasen som kan ha utplånat denna statistik.
Checkpoints och The Background Writer
pg_stat_bgwriter
postgres=# SELECT * FROM pg_stat_bgwriter;
-[ RECORD 1 ]---------+------------------------------
checkpoints_timed | 47829
checkpoints_req | 2
checkpoint_write_time | 7323
checkpoint_sync_time | 38
buffers_checkpoint | 76
buffers_clean | 0
maxwritten_clean | 0
buffers_backend | 5
buffers_backend_fsync | 0
buffers_alloc | 440
stats_reset | 2018-02-04 19:52:34.712832+00
PostgtreSQL-klustret hanterar att skriva data till disk på flera olika sätt. När det gäller "smutsiga buffertar" (data i minnet som har ändrats sedan de lästes från disken, men som ännu inte har skrivits till disken), görs detta antingen av en kontrollpunkt eller bakgrundsskrivaren. Eftersom en smutsig buffert måste skrivas till disken innan den kan frigöras eller omfördelas, är det avgörande att se till att dessa processer är finjusterade, och den här tabellen hjälper till att belysa hur det hela fungerar.
Kontrollpunkter
En kontrollpunkt sker antingen enligt schemat (representerad av parametern checkpoint_timeout), eller när den maximala mängden WAL-filer har använts sedan den senaste kontrollpunkten och måste tvinga fram en kontrollpunkt. Hur som helst, en kontrollpunkt skriver smutsiga buffertar till disken, och det finns fyra kolumner som spårar den.
Kolumnerna checkpoints_timed och checkpoints_req visar antalet schemalagda checkpoints som inträffar (tidsinställda) och antalet begärda checkpoints (även kallat forcerade). Ett högt klättringsvärde på checkpoint_req kan tyda på ett otillräckligt max_wal_size-värde.
Kolumnerna checkpoint_write_time och checkpoint_sync_time registrerar den totala tid (i millisekunder) som checkpointprocessen har ägnat åt att skriva och synkronisera till disk.
Slutligen är buffers_checkpoint det totala antalet buffertar som skrivs till disken av checkpoints.
Bakgrundsskribent
Bakgrundsskrivaren är en separat process som skriver smutsiga buffertar till disken, vilket idealiskt minskar mängden arbete som checkpointaren behöver göra.
Kolumnen buffers_clean representerar antalet buffertar som skrivits till disken av bakgrundsprocessen. Jämfört med buffers_checkpoint visar den hur mycket av arbetsbelastningen som hanteras av varje process (med den extra kunskapen att bakgrundsskribent har möjlighet att skriva buffertar flera gånger om de ändras ofta, jämfört med mindre ofta med en tidsinställd kontrollpunkt).
Maxwritten_clean representerar antalet gånger bakgrundsskribenten nådde det maximala antalet sidor att spola varje gång den körs (kontrolleras med parametern bgwriter_lru_maxpages).
Buffertar i allmänhet
De återstående kolumnerna visar oss den allmänna buffertinformationen, där buffers_backend är antalet buffertar som en backend måste skriva själv, istället för bakgrundsskrivare eller checkpointer, är buffers_backend_fsync en räkning av hur många gånger en backend behövde köra sitt eget fsync-anrop, och buffers_alloc visar antalet buffertar som har allokerats i allmänhet.
Databasaktivitet och lås
Det finns två vyer som visar aktuell användaraktivitet, pg_stat_activity och pg_locks. När de efterfrågas visar dessa information om aktuella anslutningar till databaserna och vilken typ av lås de har på vilka relationer.
pg_stat_activity
postgres=# SELECT * FROM pg_stat_activity;
-[ RECORD 1 ]----+--------------------------------
datid | 13805
datname | severalnines
pid | 29730
usesysid | 10
usename | postgres
application_name | psql
client_addr |
client_hostname |
client_port | -1
backend_start | 2018-07-21 02:29:48.976588+00
xact_start | 2018-07-21 02:30:03.73683+00
query_start | 2018-07-21 02:30:03.73683+00
state_change | 2018-07-21 02:30:03.736835+00
wait_event_type |
wait_event |
state | active
backend_xid |
backend_xmin | 559
query | SELECT first_name FROM customers WHERE customers_sid = 472;
backend_type | client backend
Allmän information
Vyn pg_stat_activity visar en rad för varje anslutning till databasen, och lite grundläggande information om den. Kolumnen datname representerar databasen som anslutningen faktiskt är ansluten till, pid är process-ID för anslutningen på själva databasvärden, och usesysid och usename representerar databasanvändaren som är ansluten.
För källan till klienten är client_addr IP-adressen till värden som anslutningen kom från, null betyder att det är en lokal unix-socket-anslutning.
Tidsstämplar
Det finns fyra tidsstämpelkolumner som visar när vissa saker startade:backend_start är när anslutningen faktiskt upprättades, xact_start är när den aktuella transaktionen startade (null om klienten inte har någon öppen transaktion), query_start är när den aktuella eller senaste frågan startade, och state_change är den tidpunkt då anslutningens tillstånd senast ändrades.
Anslutningsstatus
De sista bitarna av pg_stat_activity täcker anslutningens faktiska status. Om frågan väntar på att en annan ska släppa lås, innehåller wait_event_type information om vilken typ av wait-händelse det är, och kolumnen wait_event kommer att visa wait-händelsens namn. Det är en lång lista, men mer information finns i PostgreSQL-dokumentationen.
Slutligen visar kolumnen "tillstånd" vilket tillstånd den aktuella anslutningen är i, till exempel aktiv, inaktiv, inaktiv i transaktion, och frågekolumnen visar den faktiska frågan som körs eller senast körs.
pg_lock
SELECT * FROM pg_locks;
-[ RECORD 1 ]------+----------------
locktype | virtualxid
database |
relation |
page |
tuple |
virtualxid | 3/475862
transactionid |
classid |
objid |
objsubid |
virtualtransaction | 3/475862
pid | 29730
mode | ExclusiveLock
granted | t
fastpath | t
Tabellen pg_locks fungerar hand i hand med pg_stat_activity om man tittar på frågeaktivitet. Varje gång ett lås görs till en relation, lagras den informationen i pg_locks. Med hjälp av pid från pg_stat_activity kan vi fråga pg_locks för att se vilka relationer en anslutning kan ha låst på, vilka typer av lås det är och om låsen har beviljats eller inte.
De viktigaste kolumnerna är 'pid', som matchar pid från pg_stat_activity, 'relation' som matchar OID från pg_class, 'mode' som visar namnet på låsläget som hålls och 'granted' som anger om låset i frågan har beviljats.
Replikeringsinformation
Eftersom PostgreSQL har inbyggda replikeringsfunktioner finns det några vyer som belyser själva replikeringens prestanda och status.
Visa pg_stat_replication: innehåller en rad för varje WAL-avsändarprocess, som innehåller information om dess tillstånd, platsen för WAL-filerna den arbetar med och anslutningsinformationen för standby-värden som tar emot WAL-data för replikering.
Visa pg_stat_wal_receiver: Om klustret är ett standby-läge kommer detta att innehålla en enda rad som visar statistik om mottagarprocessen från värden.
Visa pg_stat_subscription: Om WAL-data skickas till en standby-nod kommer varje rad här att representera den prenumerationen och innehålla information om status för prenumerationerna.
Visa pg_replication_slots: Innehåller en lista över alla replikeringsplatser som finns i klustret och deras nuvarande tillstånd.
Databasspecifik metadata
Inuti varje databas finns en samling katalogtabeller som har information som är specifik för databasen som efterfrågas. Om vi letar efter specifik data från dessa tabeller måste vi se till att vi är anslutna till rätt databas när vi skickar frågorna.
Det är här som kärnan i dataanalys kan komma in, där vi kan se precis hur vår användardata nås. Från tabeller, till index, till sekvenser, frågorna som kommer in i databasen och hämtar eller ändrar data, deras åtgärder och inverkan kommer att lagras i dessa tabeller, och vi kan titta på den informationen för att fatta välgrundade beslut om hur databasen ska hanteras. väg.
Tabellmetadata
Metadata om våra användartabeller lagras i följande två tabeller, och de har varsin rad för varje användartabell som skapas i systemet. Tabellen pg_stat_user_tables innehåller statistik om användaråtkomst till tabellen, medan pg_statio_user_tables innehåller I/O-statistik för varje tabell.
OBS:Uppgifterna här är inte alltid 100 % perfekta och förlitar sig på frekventa analyser av tabellerna för att vara korrekta. Autoanalys täcker detta, men bra inställning av autoanalysprocessen så att den kan hålla bra statistik om varje tabell. Om statistiken verkar vara avstängd kommer den att uppdateras genom att köra en ANALYSE manuellt på bordet.
Tabell pg_stat_user_tables:
severalnines=> SELECT * FROM pg_stat_user_tables WHERE schemaname = 'public' AND relname = 'history';
-[ RECORD 1 ]-------+---------
relid | 2766788
schemaname | public
relname | history
seq_scan | 13817
seq_tup_read | 466841
idx_scan | 12251
idx_tup_fetch | 127652
n_tup_ins | 11
n_tup_upd | 13
n_tup_del | 3
n_tup_hot_upd | 13
n_live_tup | 3
n_dead_tup | 21
n_mod_since_analyze | 19
last_vacuum |
last_autovacuum |
last_analyze |
last_autoanalyze |
vacuum_count | 0
autovacuum_count | 0
analyze_count | 0
autoanalyze_count | 0
För vår statistik över användartabeller har vi en hel del data.
Tabellåtkomstmetoder
När klienter kommer åt data från tabellen gör de det antingen direkt eller genom index. Kolumnen "seq_scan" räknar antalet sekventiella skanningar som tabellen tog emot, och "seq_tup_read" räknar antalet tuplar som lästs genom den processen. Kolumnen "idx_scan" räknar hur många gånger ett index i tabellen användes för att hämta data.
Tabell-aktivitet
Vi har nu en handfull kolumner som räknar olika aktiviteter på bordet.
'n_tup_ins' spårar antalet infogade tupler
'n_tup_upd' spårar antalet uppdaterade tupler
'n_tup_del' spårar antalet raderade tupler
Table Tuple State
På grund av uppdateringar och raderingar kan det finnas döda tuplar som inte längre är aktiva data, och vakuumprocessen kommer så småningom att frigöra dem. Kolumnerna 'n_tup_ins' och 'n_tup_ins' spårar antalet tupler som är levande respektive döda. När döda tuplar når en viss punkt kommer ett autovakuum att startas, beroende på autovakuuminställningarna.
Tabellvakuumaktivitet
Tabellunderhåll görs genom antingen VACUUM eller AUTOVACUUM, och statistik samlas in genom ANALYS eller AUTOANALYS. De följande fyra kolumnerna innehåller datumen för när var och en av dessa operationer senast kördes:'last_vacuum', 'last_autovacuum', 'last_analyze', 'last_autoanalyze'.
Vi har också fyra mer bekväma kolumner som helt enkelt räknar hur många gånger de tidigare åtgärderna inträffar. Med hjälp av dessa kan vi se vilka tabeller som får mest aktivitet:'vacuum_count', 'autovacuum_count', 'analyze_count' och 'autoanalyze_count'.
Tabell pg_statio_user_tables:
severalnines=> SELECT * FROM pg_statio_user_tables WHERE schemaname = 'public' AND relname = history;
-[ RECORD 1 ]---+---------
relid | 2766788
schemaname | public
relname | history
heap_blks_read | 4
heap_blks_hit | 63081
idx_blks_read | 5
idx_blks_hit | 44147
toast_blks_read | 0
toast_blks_hit | 0
tidx_blks_read | 0
tidx_blks_hit | 0
I/O-utgången är användbar för att hjälpa till att förstå hur data nås under täcket. Kolumnen 'heap_blks_read' representerar antalet diskblock som lästs för denna tabell, och 'heap_blks_hit' representerar buffertblocken som läses från minnet i denna tabell. Detta är användbart för att veta om frågor som kommer åt tabellen ständigt måste gå till disk eller hämta data från minnet.
Indexstatistik i tabellen visar samma information med kolumnerna "idx_blks_read" och "idx_blks_hit".
Slutligen, om tabellen har några TOAST-tabeller, spårar kolumnerna 'toast_blks_hit' och 'toast_blks_read' toast-tabeller, medan 'tdix_blks_read' och 'tdix_blks_read' spårar indexen på dessa toast-tabeller.
Indexa metadata
pg_stat_user_indexes
severalnines=> SELECT * FROM pg_stat_user_indexes WHERE indexrelname = 'history_pkey';
-[ RECORD 1 ]-+-------------
relid | 2766797
indexrelid | 2766934
schemaname | public
relname | history
indexrelname | history_pkey
idx_scan | 43910
idx_tup_read | 98147
idx_tup_fetch | 98147
I likhet med tabellens motsvarigheter innehåller denna tabell information om indexen specifikt. En rad per index, den här tabellen visar hur många gånger indexet skannades med kolumnen 'idx_scan', hur många tupler som lästes med 'idx_tup_read' och hur många levande rader som faktiskt hämtades med 'idx_tup_fetch'.
pg_statio_user_indexes
severalnines=> SELECT * FROM pg_statio_user_indexes WHERE indexrelname = 'history_pkey';
-[ RECORD 1 ]-+-------------
relid | 2766797
indexrelid | 2766934
schemaname | public
relname | history
indexrelname | history_pkey
idx_blks_read | 2
idx_blks_hit | 49380
För pg_statio_user_indexes är de två kolumnerna tillgängliga för data "idx_blks_read" och "idx_blks_hit", som representerar antalet block som läses från disken och från minnet.
Ladda ner Whitepaper Today PostgreSQL Management &Automation med ClusterControlLäs om vad du behöver veta för att distribuera, övervaka, hantera och skala PostgreSQLDladda WhitepaperVad kan vi göra med denna data?
Var kreativ! Om förfrågningar till en specifik tabell verkar vara extremt långsamma, spåra dess aktivitet över tid, titta på hur många sekventiella skanningar den får kontra indexskanningar, titta på om den kommer till disk eller minne för data.
Om ett stort bord fortsätter att automatiskt dammsugas ofta, spåra live till döda tupler över tiden, kanske behöver det specifikt autovakuum justeras så att det kan slutföras snabbare, eller till och med kanske bordet är en kandidat för partitionering.
Eftersom vi kan se när data kommer från disk eller minne, kan vi skapa ett förhållande mellan minne och disk över tiden, och fastställa om förhållandet vid något tillfälle faller under dagen.
Mängden tabeller vi täckte gick över de stora träffarna, de viktigaste uppgifterna som är användbara att veta om databasernas inre funktion. Det finns dock många fler tabeller i systemkatalogen som innehåller situationsmässigt användbar data. Att läsa andra tabeller som tidigare hjälper till att ge insikter om databasens tillstånd i allmänhet.
För mer information om eventuella tabeller eller vyer i PostgreSQL-katalogen, besök den officiella dokumentationen här, samt information om statistikinsamlaren här.