Mesurar el temps de psql per VPN: separar l’espera de xarxa de la feina de la consulta
psql informa d’un sol número de temps transcorregut per instrucció, així que un VPN lent l’infla. Separa el temps de connexió, execució, transferència i anada i tornada abans d’ajustar qualsevol dels dos costats.
El teu informe s’acaba en aproximadament un segon a l’amfitrió de la base de dades i en quatre pel VPN, i el número que imprimeix psql assenyala directament la base de dades. Aquest número és un cronòmetre del costat del client, no una mesura del servidor. Cobreix la instrucció de sortida, l’espera d’una resposta i les files de tornada. Separar aquestes tres coses és l’única manera de saber quin costat ajustar.
Què mesura realment el temporitzador de psql
\timing on inicia un cronòmetre just abans que el client escrigui la instrucció al sòcol i l’atura quan s’ha llegit l’última fila d’aquell resultat. L’execució del propi servidor és en algun lloc dins d’aquesta finestra, i també cada mil·lisegon que els paquets passen al túnel. Res a la sortida no els separa. EXPLAIN també imprimeix un número, però aquell el produeix el servidor i exclou l’espera del client. Dos números, dues preguntes diferents.
Inicia una sessió, deixa el mesurament activat i executa la instrucció que t’interessa des de dins. Reutilitzar una sessió manté el cost de connexió fora del primer mesurament.
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';"La xifra encara inclou la transferència del resultat, que és el que vols aquí. Ja no inclou l’intercanvi de connexió i autenticació que afegiria una invocació nova.
Compara una instrucció per tres camins
Executa la mateixa instrucció pel sòcol Unix, per l’adreça LAN i pel nom d’amfitrió VPN, i compara les tres. Si només l’última és lenta, la consulta no és la variable.
Cada invocació es connecta primer i només després mesura la instrucció, així que el cost de connexió queda fora del número mentre la transferència hi queda dins. Mantén la clàusula WHERE, el recompte de files i la màquina client idèntics, o estàs comparant càrregues de treball en lloc de camins.
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;"En una LAN la diferència sol ser prou petita per ignorar-la; per VPN sovint no ho és. Ordenar els tres resultats et diu després contra quina espera atacar.
Un sòcol local lent significa feina del servidor o planificació. Un resultat LAN lent significa la consulta o el volum que mou. Només un resultat VPN lent significa latència, MTU o amplada de banda disponible al camí, i cap canvi d’índex ho arregla.
Extreu el temps d’execució del propi servidor
El servidor pot informar de quant temps hi ha passat, i aquesta xifra és la que cal comparar amb la del client. EXPLAIN amb ANALYZE executa la instrucció i imprimeix el temps de planificació i execució dins del pla, mentre que BUFFERS afegeix el comportament de la memòria cau que sovint explica una execució càlida davant d’una de freda. No l’adrecis a instruccions d’escriptura si no vols escriure. En una rèplica només de lectura és el lloc més segur per començar, i la referència de psql documenta l’abast del temporitzador al costat del client.
Per a les instruccions que l’aplicació ja executa, pg_stat_statements agrega l’execució del costat del servidor sense tornar a executar res. Les files són per consulta normalitzada, així que una entrada pot cobrir diversos punts de crida.
select calls, round(mean_exec_time::numeric, 2) as mean_ms, rows
from pg_stat_statements
order by mean_exec_time desc
limit 5;Els noms de columna varien segons la versió: PostgreSQL 13 i posteriors exposen mean_exec_time, mentre que les versions anteriors l’anomenen mean_time, així que comprova amb \d pg_stat_statements si aquesta consulta dóna error. Aquests valors exclouen la planificació i exclouen el viatge fins al teu client. Aquesta exclusió és precisament per què són útils per a la comparació.
Compta les anades i tornades, no només els mil·lisegons
Un informe construït amb dues-centes instruccions petites dependents multiplica per dues-centes qualsevol latència que afegeixi el camí. Una sola instrucció que retorna un milió de files paga aquesta latència una vegada i després paga amplada de banda durant molt de temps. Tots dos es veuen iguals en un temporitzador de client, i necessiten correccions oposades.
Mesura el recompte d’instruccions en lloc d’estimar-lo. Llegeix el total, executa l’informe una vegada, torna a llegir-lo i resta.
select sum(calls) as calls from pg_stat_statements;
-- run the report here
select sum(calls) as calls from pg_stat_statements;Si el delta és gran i cada instrucció és barata al servidor, l’agrupació és la correcció que paga. Combina consultes dependents, fes servir una sola instrucció basada en conjunts o porta el bucle des d’un cursor. A psql interactiu, \set FETCH_COUNT 1000 fa que un resultat gran arribi per lots i canvia com es comporten la transferència i la memòria del client. No redueix la feina del servidor, així que no salvarà una consulta lenta.
Revisa el túnel per retransmissions i aturades d’MTU
Quan les instruccions petites són ràpides i els resultats grans s’aturen a mig camí, la consulta sol estar bé i el camí no. Un túnel amb un MTU inferior a l’enllaç subjacent, combinat amb ICMP bloquejat, produeix exactament aquest patró: els primers paquets arriben, els grans desapareixen i la transferència penja fins que torna a intentar-ho. Els comptadors de retransmissió del costat del client ho mostren.
Vigila el sòcol i els comptadors del nucli mentre s’executa una transferència deliberadament lenta. Els totals de retransmissió són acumulatius, així que anota’ls abans i després en lloc de llegir una sola mostra.
ss -tin dst 10.40.0.12
netstat -s | grep -iE "retransmit|segments retransmitted"
ping -M do -s 1400 -c 3 10.40.0.12Les retransmissions que pugen durant la transferència, juntament amb un ping que té èxit a 1400 bytes però falla a 1472, apunten a un problema d’MTU i no a un de base de dades. Baixar l’MTU de la interfície del túnel o estrènyer l’MSS a la porta d’enllaç és la correcció habitual, i les mateixes tres ordres ho confirmen després. Si les retransmissions es mantenen planes mentre la transferència encara és lenta, mira l’amplada de banda permesa al túnel i no les pèrdues.
Una seqüència curta cobreix el proper informe lent: compara una instrucció en local, a la LAN i pel VPN; llegeix l’execució del servidor des d’EXPLAIN o pg_stat_statements; compta les crides abans i després d’una sola execució; i vigila les retransmissions mentre es mou el resultat gran. Cada pas descarta un costat del camí. Cap d’ells no requereix endevinar quin component reiniciar.