Мерење време на psql преку VPN: одделување на мрежното чекање од работата на барањето
psql пријавува еден број на изминато време по наредба, па бавниот VPN го надувува. Одделете го времето за поврзување, извршување, пренос и одење и враќање пред да подесите која било страна.
Вашиот извештај завршува за околу една секунда на домаќинот на базата на податоци и за четири преку VPN, а бројот што го печати psql покажува директно на базата. Тој број е стоперка на страната на клиентот, а не мерење на серверот. Го опфаќа барањето на патот надвор, чекањето одговор и редовите на патот назад. Одделувањето на овие три е единствениот начин да се знае која страна да се подеси.
Што всушност мери тајмерот на psql
\timing on започнува стоперка веднаш пред клиентот да го запише барањето во сокетот и ја запира кога е прочитан последниот ред од тој резултат. Извршувањето на самиот сервер се наоѓа некаде во тој прозорец, како и секоја милисекунда што пакетите ја поминуваат во тунелот. Ништо во излезот не ги одделува. EXPLAIN исто така печати број, но тој го создава серверот и го исклучува чекањето на клиентот. Два броја, две различни прашања.
Започнете една сесија, оставете мерењето време вклучено и извршете го барањето што ве интересира од нејзината внатрешност. Повторното користење сесија го држи трошокот за поврзување надвор од првото мерење.
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';"Бројот се уште го вклучува преносот на резултатот, што е она што го сакате овде. Веќе не ја вклучува размената за поврзување и потврдување што би ја додал нов повик.
Споредете едно барање на три патеки
Извршете го истото барање преку Unix сокетот, преку LAN адресата и преку името на VPN домаќинот и споредете ги трите. Ако само последното е бавно, барањето не е променливата.
Секој повик прво се поврзува и дури потоа го мери барањето, така што трошокот за поврзување останува надвор од бројот, додека преносот останува внатре. Држете ја клаузулата WHERE, бројот на редови и клиентската машина исти, инаку споредувате работни оптоварувања, а не патеки.
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 разликата обично е доволно мала за да се занемари; преку VPN често не е. Подредувањето на трите резултати потоа ви кажува на кое чекање да нападнете.
Бавниот локален сокет значи работа на серверот или планирање. Бавниот LAN резултат значи барањето или обемот што го преместува. Само бавниот VPN резултат значи задоцнување, MTU или достапна пропусност на патеката, и никакви промени во индексите не го поправаат тоа.
Извадете го сопственото време на извршување на серверот
Серверот може да пријави колку време потрошил, и токму тој број треба да се спореди со клиентскиот. EXPLAIN со ANALYZE го извршува барањето и го печати времето за планирање и извршување во планот, додека BUFFERS додава однесување на кешот што често објаснува топло извршување наспроти ладно. Не го насочувајте кон наредби за пишување освен ако не планирате да пишувате. На реплика само за читање тоа е најбезбедното место за почеток, и референца за psql го документира опсегот на тајмерот на страната на клиентот.
За барањата што апликацијата веќе ги извршува, pg_stat_statements го собира извршувањето на страната на серверот без ништо повторно да извршува. Редовите се по нормализирано барање, па еден запис може да покрие неколку места на повик.
select calls, round(mean_exec_time::numeric, 2) as mean_ms, rows
from pg_stat_statements
order by mean_exec_time desc
limit 5;Имињата на колоните се разликуваат по издание: PostgreSQL 13 и поновите го изложуваат mean_exec_time, додека постарите верзии го нарекуваат mean_time, па проверете со \d pg_stat_statements, ако тоа барање даде грешка. Овие вредности го исклучуваат планирањето и го исклучуваат патувањето до вашиот клиент. Токму тоа исклучување ги прави корисни за споредбата.
Бројте одења и враќања, не само милисекунди
Извештај составен од двесте мали зависни наредби го множи секое задоцнување што патеката го додава со двесте. Една наредба што враќа милион редови го плаќа тоа задоцнување еднаш и потоа долго плаќа пропусност. Двете изгледаат исто во клиентски тајмер и бараат спротивни поправки.
Измерете го бројот на наредби наместо да го проценувате. Прочитајте го вкупниот број, извршете го извештајот еднаш, потоа прочитајте го повторно и одземете.
select sum(calls) as calls from pg_stat_statements;
-- run the report here
select sum(calls) as calls from pg_stat_statements;Ако делтата е голема и секоја наредба е евтина на серверот, групирањето е поправката што се исплати. Комбинирајте зависни барања, користете една наредба заснована на множества или водете јамката од курсор. Во интерактивниот psql, \set FETCH_COUNT 1000 големиот резултат пристигнува во партии и го менува однесувањето на преносот и клиентската меморија. Тоа не ја намалува работата на серверот, па нема да спаси бавно барање.
Проверете го тунелот за повторни праќања и MTU застои
Кога малите наредби се брзи, а големите резултати запираат на половина пат, барањето обично е во ред, а патеката не е. Тунел чиј MTU е понизок од основната врска, заедно со блокиран ICMP, создава токму таков образец: првите пакети пристигнуваат, големите исчезнуваат, и преносот виси додека не се обиде повторно. Бројачите на повторни праќања на страната на клиентот го покажуваат тоа.
Гледајте го сокетот и бројачите на јадрото додека трае намерно бавен пренос. Збировите на повторни праќања се кумулативни, па запишете ги пред и по, наместо да читате еден примерок.
ss -tin dst 10.40.0.12
netstat -s | grep -iE "retransmit|segments retransmitted"
ping -M do -s 1400 -c 3 10.40.0.12Повторните праќања што растат за време на преносот, заедно со ping што успева на 1400 бајти, но не успева на 1472, укажуваат на MTU проблем, а не на проблем со базата. Намалувањето на MTU на интерфејсот на тунелот или стегањето на MSS на портата е вообичаената поправка, и истите три команди го потврдуваат потоа. Ако повторните праќања останат рамни додека преносот е се уште бавен, гледајте ја пропусноста дозволена на тунелот, а не загубите.
Кратка низа го покрива следниот бавен извештај: споредете едно барање локално, на LAN и преку VPN; прочитајте го извршувањето на серверот од EXPLAIN или pg_stat_statements; избројте повици пред и по едно извршување; и гледајте повторни праќања додека се движи големиот резултат. Секој чекор исклучува една страна од патеката. Ниту еден не бара да се погоди кој компонент да се рестартира.