sql >> Database teknologi >  >> RDS >> PostgreSQL

Forståelse og læsning af PostgreSQL-systemkataloget

Administration af databaser er ikke en lille opgave, og det kan nemt være frustrerende uden at vide, hvad der sker under dynen. Uanset om du prøver at finde ud af, om nye indekser er nyttige, transaktionen tæller på en database på et bestemt tidspunkt, eller hvem der er forbundet til databasen på et givet tidspunkt, er data, der gør det muligt for administratorerne virkelig at vide, hvordan deres databaser klarer sig. Heldigvis, med PostgreSQL, er disse data for alt dette tilgængelige i PostgreSQL-systemkataloget.

PostgreSQL-systemkataloget er et skema med tabeller og visninger, der indeholder metadata om alle de andre objekter i databasen og mere. Med den kan vi opdage, hvornår forskellige operationer sker, hvordan tabeller eller indekser tilgås, og endda om databasesystemet læser information fra hukommelsen eller har brug for at hente data fra disken.

Her vil vi gennemgå en oversigt over systemkataloget og fremhæve, hvordan man læser det, og hvordan man henter nyttig information fra det. Nogle af metadataene er ligetil, og andre stykker kræver lidt fordøjelse for at generere rigtig nyttig information. Uanset hvad, så giver PostgreSQL os en fantastisk platform til at bygge den information, vi har brug for om selve databasen.

PostgreSQL-kataloget

PostgreSQL gemmer metadataoplysningerne om databasen og klyngen i skemaet 'pg_catalog'. Denne information bruges delvist af PostgreSQL selv til at holde styr på tingene selv, men den præsenteres også, så eksterne personer/processer også kan forstå indersiden af ​​databaserne.

PostgreSQL-kataloget har en ret solid regel:Se, rør ikke. Mens PostgreSQL gemmer al denne information i tabeller, som enhver anden applikation ville, administreres dataene i tabellerne fuldt ud af PostgreSQL selv og bør ikke ændres, medmindre det er en absolut nødsituation, og selv da er en genopbygning sandsynligvis i orden efterfølgende.

Vi vil gennemgå et par nyttige katalogtabeller, hvordan man læser dataene og smarte ting, vi kan gøre med selve dataene. Der er en del tabeller i kataloget, som vi ikke vil gennemgå, men al information om disse forskellige tabeller kan findes i PostgreSQLs officielle dokumentation.

Systemdækkende metadata

En god del af de tabeller, vi kan forespørge på i kataloget, er "system-wide" tabeller, hvor det er ligegyldigt, hvilken database vi er forbundet til, dataene repræsenterer hele klyngen, ingen enkelt database.

Databaseoplysninger

Generel databaseinformation gemmes i pg_database og statistik gemmes 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 indeholder en række for hver database i klyngen, inklusive de tre, der kommer ud af boksen (postgres, template0 og template1). Denne række indeholder oplysninger om kodning, forbindelsesgrænse og andre grundlæggende metadata.

Spalter af interesse:

oid - Objektidentifikatoren, som ikke vises i et forespørgselsoutput, medmindre der refereres direkte. Dette nummer vil matche en mappe i clusters databiblioteket /base/.
datname - Navnet på databasen.
datdba - Ejeren af ​​databasen, oid referencer pg_authid .oid.
kodning - Tegnkodningen for denne database, pg_encoding_to_char() vil konvertere til et læsbart navn.
datconnlimit - Det maksimale antal samtidige forbindelser tilladt på databasen.
dattablespace - Den standard tablespace for denne database, referencer 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

Denne statistiktabel er, hvor vi får interessante og nyttige data. Hver række i denne tabel indeholder livedata for hver database og kan eksporteres med jævne mellemrum for at blive sporet over tid, hvis man ønsker at overvåge ændringer.

Transaktioner

Transaktionsoplysninger kan findes i kolonnerne xact_commit og xact_rollback, som indeholder antallet af transaktioner, som databasen har henholdsvis begået og rullet tilbage. Dette vil hjælpe med at vise, hvor aktiv en database er, samt spotte mulige fejl med programmer, der kan fejle / rulle tilbage i en alarmerende hastighed.

Disk- og hukommelsesadgang

Information om, hvorvidt data hentes fra disk eller hukommelse, gemmes i kolonnerne blks_read og blks_hit. Blks_read viser antallet af blokke, som denne database læste fra disken, mens blks_hit viser antallet af blokke, der blev fundet i PostgreSQLs buffercache (repræsenteret af shared_buffers-parameteren). Da RAM er meget hurtigere end disk, ville vi ideelt set se blks_hit konsekvent højere end blks_read, og hvis ikke, kan vi revurdere vores tilgængelige hukommelse.

Tupler

De næste par kolonner omhandler tupler. Tup_returned er antallet af rækker, der returneres i databasen, som er antallet af rækker, der læses af sekventielle scanninger, hvis fra en tabel, eller antallet af indeksposter, der returneres fra et indeks”. Tup_fetched er antallet af rækker, der er hentet i databasen, hvilket betyder, at de var et resultat af bitmap-scanninger, hvilket er antallet af tabelrækker, der er hentet af bitmap-scanninger, hvis fra en tabel, eller tabelrækker, der er hentet ved simple indeks-scanninger, hvis du bruger et indeks.

Vi har også tup_inserted, tup_updated og tup_deleted, som repræsenterer antallet af tupler, der henholdsvis er indsat, opdateret og slettet i denne database. Dette vil hjælpe med at forstå, hvordan data kommer ind, ændres og forlader databasen. Da opdaterede og slettede tupler resulterer i døde rækker, ville høje værdier i disse kolonner foreslå, at autovakuum-operationer indstilles til at opfylde behovene for databaseaktiviteten.

Konflikter

Hvis den pågældende database er en standby-server, er kolonnekonflikterne praktisk som en måde at spore, hvor mange forespørgsler, der blev annulleret på grund af konflikter med, at standbyen er i 'gendannelsestilstand'. Hvis ikke en standby-klynge, kan denne kolonne ignoreres.

Midlertidige filer/data

Til tider skal forespørgsler skrive til midlertidige filer. Dette kan ske, når mængden af ​​work_mem, der er allokeret til forbindelsen, er brugt op og skal fortsætte en sorteringsoperation på disken i stedet for i hukommelsen. Kolonnen temp_files sporer antallet af disse filer, der blev oprettet, og temp_bytes sporer den samlede størrelse af alle anvendte midlertidige filer. Disse data kan hjælpe med at informere work_mem tuning eller endda finde forespørgsler, der kunne bruge omskrivning, hvis den midlertidige filstørrelse er for stor.

Deadlocks

Deadlocks-kolonnen sporer, hvor mange gange en deadlock opstår. Da et dødvande kan forårsage fejl for forespørgsler, der ellers ikke ville fejle, er det godt at spore dette og sikre, at applikationer ikke træder hinandens fødder.

Læse- og skrivetider

Kolonnerne blk_read_time og blk_write_time sporer det samlede antal millisekunder, som backends i databasen bruger på at læse og skrive data, hvilket kan være nyttigt, hvis man forsøger at sammenligne/forbedre disk læse/skrivehastighed

Statistik nulstillet

Denne kolonne, stats_reset, viser blot et tidsstempel (med tidszone) for sidste gang, statistikken nævnt i denne række er blevet nulstillet. En nulværdi betyder, at de ikke er blevet nulstillet siden starten, eller endda muligvis et nedbrud af databasen, hvilket kan have udslettet disse statistikker.

Checkpoints og 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-klyngen administrerer skrivning af data til disk på flere forskellige måder. Med hensyn til 'beskidte buffere' (data i hukommelsen, der er blevet ændret siden læst fra disk, men endnu ikke har fået den ændring skrevet til disk), gøres dette enten af ​​et kontrolpunkt eller baggrundsskriveren. Da en beskidt buffer skal skrives til disken, før den kan frigives eller omfordeles, er det afgørende at sikre, at disse processer er finjusteret, og denne tabel hjælper med at kaste lys over, hvordan det hele fungerer.

Kontrolpunkter

Et kontrolpunkt sker enten efter planen (repræsenteret ved parameteren checkpoint_timeout), eller når den maksimale mængde WAL-filer er blevet brugt siden sidste kontrolpunkt, og skal tvinge et kontrolpunkt. Uanset hvad, skriver et kontrolpunkt beskidte buffere til disken, og der er fire kolonner, der sporer det.

Kolonnerne checkpoints_timed og checkpoints_req viser antallet af planlagte checkpoints, der forekommer (tidsindstillet) og antallet af anmodede checkpoints (også kaldet forcerede). En høj stigningsværdi på checkpoint_req kunne tyde på en utilstrækkelig max_wal_size værdi.

Kolonnerne checkpoint_write_time og checkpoint_sync_time registrerer den samlede tid (i millisekunder), som checkpoint-processen har brugt på at skrive og synkronisere til disk.

Endelig er buffers_checkpoint det samlede antal buffere skrevet til disken af ​​checkpoints.

Baggrundsforfatter

Baggrundsskriveren er en separat proces, der skriver beskidte buffere til disken, hvilket ideelt set reducerer mængden af ​​arbejde, som checkpointeren skal udføre.

Kolonnen buffers_clean repræsenterer antallet af buffere skrevet til disken af ​​baggrundsprocessen. Sammenlignet med buffers_checkpoint viser det, hvor meget af arbejdsbyrden, der håndteres af hver proces (med den tilføjede viden, at baggrundsforfatteren har mulighed for at skrive buffere flere gange, hvis de ændres ofte, kontra sjældnere med et tidsindstillet kontrolpunkt).

Maxwritten_clean repræsenterer antallet af gange, som baggrundsforfatteren nåede det maksimale antal sider at tømme, hver gang den kører (kontrolleret med parameteren bgwriter_lru_maxpages).

Buffere generelt

De resterende kolonner viser os den generelle bufferinformation, hvor buffers_backend er antallet af buffere, som en backend selv skulle skrive, i stedet for baggrundsskriver eller checkpointer, er buffers_backend_fsync en optælling af, hvor mange gange en backend skulle udføre sit eget fsync-kald, og buffers_alloc viser antallet af buffere, der er blevet tildelt generelt.

Databaseaktivitet og låse

Der er to visninger, der viser aktuel brugeraktivitet, pg_stat_activity og pg_locks. Når de bliver spurgt, viser disse oplysninger om aktuelle forbindelser til databaserne, og hvilke slags låse de har på hvilke 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
Generel information

Visningen pg_stat_activity viser en række for hver forbindelse til databasen og nogle grundlæggende oplysninger om den. Kolonnen datname repræsenterer den database, forbindelsen faktisk er forbundet til, pid er proces-id'et for forbindelsen på selve databaseværten, og usesysid og usename repræsenterer den tilsluttede databasebruger.

For kilden til klienten er client_addr IP-adressen på den vært, forbindelsen kom fra, null betyder, at det er en lokal unix-socket-forbindelse.

Tidsstempler

Der er fire tidsstempelkolonner, der viser, hvornår visse ting startede:backend_start er, hvornår forbindelsen faktisk blev etableret, xact_start er, når den aktuelle transaktion startede (nul, hvis klienten ikke har nogen åben transaktion), query_start er, når den aktuelle eller seneste forespørgsel startede, og state_change er det tidspunkt, hvor forbindelsens tilstand sidst blev ændret.

Forbindelsesstatus

De sidste bits af pg_stat_activity dækker forbindelsens faktiske status. Hvis forespørgslen venter på en anden for at udløse låse, indeholder wait_event_type nogle oplysninger om, hvilken slags wait-hændelse det er, og kolonnen wait_event vil vise wait-hændelsens navn. Det er en lang liste, men mere information findes i PostgreSQL-dokumentationen.

Til sidst viser kolonnen 'tilstand', hvilken tilstand den aktuelle forbindelse er i, såsom aktiv, inaktiv, inaktiv i transaktion, og forespørgselskolonnen vil vise den faktiske forespørgsel, der køres, eller senest kørte.

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 arbejder hånd i hånd med pg_stat_activity, hvis man ser på forespørgselsaktivitet. Hver gang der laves en lås til en relation, gemmes denne information i pg_locks. Ved at bruge pid'en fra pg_stat_activity kan vi forespørge pg_locks for at se, hvilke relationer en forbindelse kan have låse på, hvilke slags låse det er, og om låsene er blevet tildelt eller ej.

De vigtigste kolonner er 'pid', som matcher pid'en fra pg_stat_activity, 'relation', som matcher OID'en fra pg_class, 'mode', der viser navnet på låsetilstanden holdt, og 'granted', som angiver, om låsen i spørgsmålet er blevet givet.

Replikeringsoplysninger

Da PostgreSQL har indbygget replikeringsfunktioner, er der nogle få visninger, der kaster lys over selve replikeringens ydeevne og status.

Se pg_stat_replication: indeholder en række for hver WAL-afsenderproces, der indeholder oplysninger om dens tilstand, placeringen af ​​de WAL-filer, den arbejder på, og forbindelsesoplysningerne for den standby-vært, der modtager WAL-dataene til replikering.

Se pg_stat_wal_receiver: Hvis klyngen er en standby, vil denne indeholde en enkelt række, der viser statistik om modtagerprocessen fra værten.

Se pg_stat_subscription: Hvis der sendes WAL-data til en standby-node, vil hver række her repræsentere det pågældende abonnement og indeholde oplysninger om status for abonnementerne.

Se pg_replication_slots: Indeholder en liste over alle de replikeringspladser, der findes på klyngen, og deres aktuelle tilstand.

Databasespecifikke metadata

Inde i hver database er der en samling af katalogtabeller, der har oplysninger, der er specifikke for den database, der forespørges. Hvis vi leder efter specifikke data fra disse tabeller, skal vi sørge for, at vi er forbundet til den rigtige database, mens vi udsteder forespørgslerne.

Det er her, hjertet af dataanalyse kan komme ind, hvor vi kan se, hvordan vores brugerdata bliver tilgået. Fra tabeller, til indekser, til sekvenser, de forespørgsler, der kommer ind i databasen og henter eller ændrer data, deres handlinger og indvirkning vil blive gemt i disse tabeller, og vi kan se på den information for at træffe informerede beslutninger om styring af databasen vej.

Tabelmetadata

Metadata om vores brugertabeller er gemt i de følgende to tabeller, og de har hver en række for hver brugertabel, der oprettes i systemet. Tabellen pg_stat_user_tables indeholder statistik om brugeradgang til tabellen, mens pg_statio_user_tables indeholder I/O-statistik for hver tabel.

BEMÆRK:Dataene her er ikke altid 100 % perfekte og er afhængige af hyppige analyser af tabellerne for at være korrekte. Autoanalyse dækker over dette, men god tuning af autoanalyseprocessen, så den kan føre god statistik om hver tabel. Hvis statistikken ser ud til at være slået fra, vil kørsel af en ANALYSE manuelt på bordet opdatere dem.

Tabel 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

Til vores brugertabelstatistik har vi en del stykker data.

Tabeladgangsmetoder

Når klienter får adgang til data fra tabellen, sker det enten direkte eller gennem indekser. Kolonnen 'seq_scan' tæller antallet af sekventielle scanninger, tabellen modtog, og 'seq_tup_read' tæller antallet af tuples læst gennem den proces. Kolonnen 'idx_scan' tæller, hvor mange gange et indeks i tabellen blev brugt til at hente data.

Table Tuple-aktivitet

Vi har nu en håndfuld kolonner, der tæller forskellige aktiviteter på bordet.

'n_tup_ins' sporer antallet af indsatte tupler

'n_tup_upd' sporer antallet af opdaterede tupler

'n_tup_del' sporer antallet af slettede tupler

Tabel tuple-tilstand

På grund af opdateringer og sletninger kan der være døde tupler, der ikke længere er aktive data, og vakuumprocessen vil i sidste ende frigøre dem. Kolonnerne 'n_tup_ins' og 'n_tup_ins' sporer antallet af tupler, der er henholdsvis levende og døde. Når døde tupler når et bestemt punkt, vil en autovakuum blive startet, afhængigt af autovakuumindstillingerne.

Tabelvakuumaktivitet

Bordvedligeholdelse udføres enten gennem VACUUM eller AUTOVACUUM, og statistik indsamles gennem ANALYSE eller AUTOANALYSE. De næste fire kolonner indeholder datoerne for, hvornår hver af disse operationer sidst blev kørt:'last_vacuum', 'last_autovacuum', 'last_analyze', 'last_autoanalyze'.

Vi har også fire mere praktiske kolonner, der blot tæller, hvor mange gange de tidligere handlinger forekommer. Ved at bruge disse kan vi se, hvilke tabeller der får mest aktivitet:'vacuum_count', 'autovacuum_count', 'analyze_count' og 'autoanalyze_count'.

Tabel 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-outputtet er nyttigt til at hjælpe med at forstå, hvordan der tilgås data under coveret. Kolonnen 'heap_blks_read' repræsenterer antallet af diskblokke læst for denne tabel, og 'heap_blks_hit' repræsenterer bufferblokkene læst fra hukommelsen i denne tabel. Dette er nyttigt at vide, hvis forespørgsler, der får adgang til tabellen, konstant skal gå til disken eller hente dataene fra hukommelsen.

Indeksstatistik i tabellen viser de samme oplysninger med kolonnerne "idx_blks_read" og "idx_blks_hit".

Til sidst, hvis tabellen har nogen TOAST-tabeller, sporer kolonnerne 'toast_blks_hit' og 'toast_blks_read' toast-tabeller, mens 'tdix_blks_read' og 'tdix_blks_read' sporer indekserne på disse toast-tabeller.

Indeks 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

Ligesom tabellens modstykker, indeholder denne tabel information om indeksene specifikt. En række pr. indeks, denne tabel viser, hvor mange gange indekset blev scannet med kolonnen 'idx_scan', hvor mange tuples der blev læst med 'idx_tup_read', og hvor mange live rækker der rent faktisk blev hentet 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

For pg_statio_user_indexes er de to kolonner, der er tilgængelige for data, 'idx_blks_read' og 'idx_blks_hit', der repræsenterer antallet af blokke, der er læst fra disken og fra hukommelsen.

Download Whitepaper Today PostgreSQL Management &Automation med ClusterControlFå flere oplysninger om, hvad du skal vide for at implementere, overvåge, administrere og skalere PostgreSQLDownload Whitepaper

Hvad kan vi gøre med disse data?

Bliv kreativ! Hvis forespørgsler til en specifik tabel ser ud til at være ekstremt langsomme, skal du spore dens aktivitet over tid, se på, hvor mange sekventielle scanninger den får i forhold til indeksscanninger, se om den skal til disk eller hukommelse for dataene.

Hvis et stort bord bliver ved med at blive autostøvsuget ofte, kan du spore live til døde tupler over tid, måske har det specifikt brug for autovakuum for at blive justeret, så det kan fuldføre hurtigere, eller måske er bordet måske en kandidat til partitionering.

Da vi kan se, hvornår data kommer fra disk eller hukommelse, kan vi skabe et forhold mellem hukommelse og disk over tid og finde ud af, om forholdet på noget tidspunkt falder i løbet af dagen.

Mængden af ​​tabeller, vi dækkede, gik over de store hitters, de vigtigste data, der er nyttige at vide om databasernes indre funktion. Der er dog mange flere tabeller i systemkataloget, der indeholder situationsmæssigt nyttige data. At læse andre tabeller som før vil hjælpe med at give indsigt i databasens helbred generelt.

For mere information om eventuelle tabeller eller visninger i PostgreSQL-kataloget, besøg den officielle dokumentation her, samt information om statistikindsamleren her.


  1. Migrering af en Oracle-database fra AWS EC2 til AWS RDS, del 3

  2. Sådan fungerer CHR() i MariaDB

  3. FEJL 1452:Kan ikke tilføje eller opdatere en underordnet række:en fremmednøglebegrænsning mislykkes

  4. Virkningen af ​​at definere VARCHAR2-søjle med større længde