psql időmérés VPN-en át: a hálózati várakozás elválasztása a lekérdezés munkájától
A psql utasításonként egyetlen eltelt időt számol, ezért egy lassú VPN felhúzza. Válassza szét a kapcsolódás, a végrehajtás, az átvitel és az oda-vissza út idejét, mielőtt bármelyik oldalt hangolja.
A jelentése nagyjából egy másodperc alatt elkészül az adatbázis-gazdagépen és négy alatt a VPN-en, és a psql által kiírt szám egyenesen az adatbázisra mutat. Az a szám kliensoldali stopperóra, nem a kiszolgáló mérése. Lefedi az utasítást kifelé menet, a válaszra várakozást és a sorokat visszafelé. E három szétválasztása az egyetlen módja annak, hogy tudja, melyik oldalt kell hangolni.
Mit mér valójában a psql időmérője
\timing on elindít egy stopperórát közvetlenül azelőtt, hogy a kliens kiírná az utasítást a socketbe, és megállítja, amikor az eredmény utolsó sora beolvasásra került. A kiszolgáló saját végrehajtása valahol ezen az ablakon belül van, és minden ezredmásodperc is, amit a csomagok az alagútban töltenek. A kimenetben semmi sem választja el őket. Az EXPLAIN is kiír egy számot, de azt a kiszolgáló állítja elő, és kizárja a kliens várakozását. Két szám, két különböző kérdés.
Indítson egy munkamenetet, hagyja bekapcsolva az időmérést, és futtassa a számára fontos utasítást belülről. A munkamenet újrafelhasználása a kapcsolódás költségét kívül tartja az első mérésen.
psql "host=db.internal port=5432 dbname=appdb user=app" \
-c "\timing on" \
-c "select count(*) from orders where created_at > now() - interval '1 day';"A szám továbbra is tartalmazza az eredmény átvitelét, ami itt éppen a kívánt dolog. Már nem tartalmazza a kapcsolódási és hitelesítési cserét, amelyet egy új hívás hozzáadna.
Hasonlítson össze egy utasítást három útvonalon
Futtassa ugyanazt az utasítást a Unix socketen, a LAN-címen és a VPN-gazdagépnéven át, és hasonlítsa össze a hármat. Ha csak az utolsó lassú, a lekérdezés nem a változó.
Minden hívás először kapcsolódik, és csak utána méri az utasítást, így a kapcsolódás költsége kívül marad a számon, míg az átvitel benne marad. Tartsa azonosan a WHERE záradékot, a sorszámot és az ügyfélgépet, különben munkaterheléseket hasonlít össze útvonalak helyett.
psql -h /var/run/postgresql -U app -d appdb -c "\timing on" -c "select count(*) from orders;"
psql -h 10.40.0.12 -U app -d appdb -c "\timing on" -c "select count(*) from orders;"
psql -h db.vpn.internal -U app -d appdb -c "\timing on" -c "select count(*) from orders;"LAN-on a különbség általában elég kicsi az elhanyagoláshoz; VPN-en gyakran nem az. A három eredmény rendezése után megtudja, melyik várakozást támadja.
A lassú helyi socket kiszolgálómunkát vagy tervezést jelent. A lassú LAN-eredmény a lekérdezést vagy az általa mozgatott mennyiséget jelenti. Csak a lassú VPN-eredmény jelent késleltetést, MTU-t vagy elérhető sávszélességet az útvonalon, és ezen semmilyen indexváltozás nem segít.
Hozza ki a kiszolgáló saját végrehajtási idejét
A kiszolgáló jelentheti, mennyi időt töltött el, és éppen ezt a számot kell a kliens száma mellé tenni. Az EXPLAIN ANALYZE-dzsel futtatja az utasítást, és a terven belül kiírja a tervezési és végrehajtási időt, a BUFFERS pedig hozzáadja a gyorsítótár viselkedését, amely gyakran megmagyarázza a meleg futást a hideggel szemben. Ne irányítsa író utasításokra, ha nem akar írni. Egy csak olvasható replikán ez a legbiztonságosabb kezdőhely, és a psql-referencia dokumentálja az időmérő kliensoldali hatókörét.
Azokhoz az utasításokhoz, amelyeket az alkalmazás már futtat, a pg_stat_statements kiszolgálóoldali végrehajtást gyűjt anélkül, hogy bármit újrafuttatna. A sorok normalizált lekérdezésenként értendők, így egy bejegyzés több hívási helyet fedhet le.
select calls, round(mean_exec_time::numeric, 2) as mean_ms, rows
from pg_stat_statements
order by mean_exec_time desc
limit 5;Az oszlopnevek kiadásonként eltérnek: a PostgreSQL 13 és újabbak mean_exec_time néven teszik közzé, míg a régebbi verziók mean_time-nak nevezik, ezért ellenőrizze ezzel: \d pg_stat_statements, ha ez a lekérdezés hibát ad. Ezek az értékek kizárják a tervezést és kizárják az utat a klienséhez. Éppen ez a kizárás teszi őket hasznossá az összehasonlításhoz.
Számolja az oda-vissza utakat, ne csak az ezredmásodperceket
A kétszáz kis függő utasításból épült jelentés a kétszázzal szorozza az útvonal által hozzáadott késleltetést. Egyetlen utasítás, amely egymillió sort ad vissza, egyszer fizet ezért a késleltetésért, majd sokáig fizet sávszélességet. Mindkettő ugyanúgy néz ki egy kliens időmérőjében, és ellentétes javításokat igényelnek.
Mérje meg az utasítások számát ahelyett, hogy becsülné. Olvassa le az összeget, futtassa le a jelentést egyszer, majd olvassa le újra, és vonja ki.
select sum(calls) as calls from pg_stat_statements;
-- run the report here
select sum(calls) as calls from pg_stat_statements;Ha a delta nagy, és minden utasítás olcsó a kiszolgálón, a kötegelés az a javítás, amely megtérül. Kombinálja a függő lekérdezéseket, használjon egy halmazalapú utasítást, vagy kurzorból vezesse a ciklust. Az interaktív psql-ben, \set FETCH_COUNT 1000 a nagy eredmény kötegekben érkezik, és megváltoztatja az átvitel és a kliensmemória viselkedését. Nem csökkenti a kiszolgáló munkáját, ezért nem ment meg egy lassú lekérdezést.
Ellenőrizze az alagutat újraküldések és MTU-elakadások szempontjából
Amikor a kis utasítások gyorsak, a nagy eredmények pedig félúton elakadnak, a lekérdezés általában rendben van, az útvonal pedig nem. Az alagút, amelynek MTU-ja alacsonyabb a mögöttes kapcsolatnál, blokkolt ICMP-vel párosulva pontosan ezt a mintát hozza: az első csomagok megérkeznek, a nagyok eltűnnek, és az átvitel addig lóg, amíg újra nem próbálkozik. A kliensoldali újraküldésszámlálók ezt mutatják.
Figyelje a socketet és a kernel számlálóit, miközben szándékosan lassú átvitel fut. Az újraküldési összegek kumulatívak, ezért jegyezze fel őket előtte és utána, ahelyett hogy egyetlen mintát olvasna.
ss -tin dst 10.40.0.12
netstat -s | grep -iE "retransmit|segments retransmitted"
ping -M do -s 1400 -c 3 10.40.0.12Az átvitel alatt növekvő újraküldések, együtt azzal a pinggel, amely 1400 byte-nál sikerül, de 1472-nél meghiúsul, MTU-problémára utalnak, nem adatbázis-problémára. Az alagút interfész MTU-jának csökkentése vagy az MSS szorítása a gatewayen a szokásos javítás, és ugyanaz a három parancs igazolja utána. Ha az újraküldések laposak maradnak, miközben az átvitel még mindig lassú, az alagútnak engedélyezett sávszélességet nézze, nem a veszteséget.
Egy rövid sorrend lefedi a következő lassú jelentést: hasonlítson össze egy utasítást helyben, LAN-on és VPN-en; olvassa ki a kiszolgáló végrehajtását az EXPLAIN-ből vagy a pg_stat_statements-ből; számolja a hívásokat egy futtatás előtt és után; és figyelje az újraküldéseket, miközben a nagy eredmény mozog. Minden lépés kizárja az útvonal egyik oldalát. Egyik sem igényli annak kitalálását, melyik összetevőt kell újraindítani.