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-ից, հաշվեք կանչերը մեկ գործարկումից առաջ և հետո, և հետևեք կրկնակի ուղարկումներին, մինչ մեծ արդյունքը շարժվում է։ Յուրաքանչյուր քայլ բացառում է ուղու մի կողմը։ Դրանցից ոչ մեկը չի պահանջում գուշակել, թե որ բաղադրիչը վերագործարկել։