Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Ալեքսեյ Լեսովսկու 2015 թվականի զեկույցի արտագրում «Խորը սուզվել PostgreSQL ներքին վիճակագրության մեջ»

Հրաժարում զեկույցի հեղինակից. Նշում եմ, որ այս զեկույցը թվագրված է 2015 թվականի նոյեմբերին՝ անցել է ավելի քան 4 տարի և անցել է շատ ժամանակ։ Զեկույցում քննարկված 9.4 տարբերակն այլևս չի աջակցվում: Վերջին 4 տարիների ընթացքում թողարկվել է 5 նոր թողարկում, որոնցում ի հայտ են եկել բազմաթիվ նորամուծություններ, բարելավումներ և փոփոխություններ վիճակագրության վերաբերյալ, իսկ որոշ նյութեր հնացած են և անտեղի: Երբ ես վերանայեցի, ես փորձեցի նշել այս վայրերը, որպեսզի չմոլորեցնեմ ձեզ ընթերցողին: Այս տեղերը ես չեմ վերաշարադրել, դրանք շատ են, և արդյունքում բոլորովին այլ զեկույց կստացվի։

PostgreSQL DBMS-ը հսկայական մեխանիզմ է, և այս մեխանիզմը բաղկացած է բազմաթիվ ենթահամակարգերից, որոնց համակարգված աշխատանքը ուղղակիորեն ազդում է DBMS-ի աշխատանքի վրա: Գործողության ընթացքում հավաքվում են վիճակագրություն և բաղադրիչների շահագործման մասին տեղեկատվություն, ինչը թույլ է տալիս գնահատել PostgreSQL-ի արդյունավետությունը և միջոցներ ձեռնարկել՝ բարելավելու աշխատանքը: Այնուամենայնիվ, այս տեղեկատվությունը շատ է, և այն ներկայացված է բավականին պարզեցված տեսքով: Այս տեղեկատվության մշակումը և դրա մեկնաբանումը երբեմն բոլորովին ոչ տրիվիալ խնդիր է, և գործիքների և կոմունալ ծառայությունների «կենդանաբանական այգին» կարող է հեշտությամբ շփոթեցնել նույնիսկ առաջադեմ DBA-ին:
Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի


Բարի օր Իմ անունը Ալեքսեյ է: Ինչպես ասաց Իլյան, ես կխոսեմ PostgreSQL վիճակագրության մասին։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

PostgreSQL գործունեության վիճակագրություն. PostgreSQL-ն ունի երկու վիճակագրություն. Գործունեության վիճակագրություն, որը կքննարկվի։ Եվ ժամանակացույցի վիճակագրություն տվյալների բաշխման վերաբերյալ: Ես կոնկրետ կխոսեմ PostgreSQL-ի գործունեության վիճակագրության մասին, որը թույլ է տալիս դատել կատարողականը և ինչ-որ կերպ բարելավել այն։

Ես ձեզ կասեմ, թե ինչպես արդյունավետ կերպով օգտագործել վիճակագրությունը՝ լուծելու մի շարք խնդիրներ, որոնք դուք ունեք կամ կարող եք ունենալ:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Ի՞նչ չի լինի զեկույցում. Զեկույցում ես չեմ անդրադառնա ժամանակացույցի վիճակագրությանը, քանի որ. սա առանձին թեմա է առանձին զեկույցի համար, թե ինչպես են տվյալները պահվում տվյալների բազայում և ինչպես է հարցման պլանավորողը պատկերացում ստանում այս տվյալների որակական և քանակական բնութագրերի մասին:

Եվ գործիքների ակնարկներ չեն լինի, ես չեմ համեմատի մի ապրանքը մյուսի հետ: Գովազդ չի լինելու. Եկեք թողնենք սա:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Ես ուզում եմ ձեզ ցույց տալ, որ վիճակագրության օգտագործումը օգտակար է: Դա անհրաժեշտ է. Օգտագործեք այն անվախ: Մեզ միայն անհրաժեշտ է պարզ SQL և SQL-ի հիմնական գիտելիքներ:

Եվ մենք կխոսենք, թե որ վիճակագրությունն ընտրել խնդիրները լուծելու համար:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Եթե ​​նայենք PostgreSQL-ին և գործարկենք հրաման օպերացիոն համակարգում՝ գործընթացները դիտելու համար, կտեսնենք «սև արկղ»: Մենք կտեսնենք ինչ-որ պրոցեսներ, որոնք ինչ-որ բան են անում, և անվան տակ կարելի է մոտավորապես պատկերացնել, թե ինչ են անում այնտեղ, ինչ են անում։ Բայց, փաստորեն, սա սև արկղ է, մենք չենք կարող ներս նայել։

Մենք կարող ենք դիտարկել պրոցեսորի բեռնվածությունը top, մենք կարող ենք տեսնել հիշողության օգտագործումը որոշ համակարգի կոմունալ ծրագրերի կողմից, բայց մենք չենք կարողանա նայել PostgreSQL-ի ներսում: Դրա համար մեզ անհրաժեշտ են այլ գործիքներ:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Եվ շարունակելով՝ կասեմ, թե որտեղ է ծախսվում ժամանակը։ Եթե ​​PostgreSQL-ն ներկայացնենք նման սխեմայի տեսքով, ապա հնարավոր կլինի պատասխանել, թե որտեղ է ծախսվում ժամանակը։ Սրանք երկու բան են. դա ծրագրերից հաճախորդի հարցումների մշակումն է և ֆոնային առաջադրանքները, որոնք PostgreSQL-ն կատարում է այն գործարկելու համար:

Եթե ​​մենք սկսենք նայել վերևի ձախ անկյունում, մենք կարող ենք տեսնել, թե ինչպես են մշակվում հաճախորդների հարցումները: Հարցումը գալիս է հավելվածից և հաճախորդի նիստ է բացվում հետագա աշխատանքի համար: Հարցումը փոխանցվում է ժամանակացույցին: Պլանավորողը կառուցում է հարցման պլան: Այն հետագայում ուղարկում է կատարման: Սեղանների և ինդեքսների հետ կապված I/O բլոկների մի տեսակ կա: Անհրաժեշտ տվյալները սկավառակներից ընթերցվում են հիշողության մեջ հատուկ տարածքում, որը կոչվում է «համօգտագործվող բուֆերներ»: Հարցման արդյունքները, եթե դրանք թարմացվում են, ջնջվում են, գրանցվում են WAL-ի գործարքների գրանցամատյանում: Որոշ վիճակագրական տեղեկություններ մտնում են գրանցամատյան կամ վիճակագրություն հավաքող: Իսկ հարցման արդյունքը վերադարձվում է հաճախորդին։ Դրանից հետո հաճախորդը կարող է ամեն ինչ կրկնել նոր խնդրանքով։

Ի՞նչ ունենք ֆոնային առաջադրանքների և ֆոնային գործընթացների հետ: Մենք ունենք մի քանի գործընթացներ, որոնք պահում են տվյալների բազան և աշխատում են նորմալ գործող ռեժիմով: Այս գործընթացները նույնպես կներառվեն զեկույցում. դրանք են autovacuum, checkpointer, replication հետ կապված գործընթացներ, background writer: Զեկուցելիս կանդրադառնամ դրանցից յուրաքանչյուրին։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Ի՞նչ խնդիրներ կան վիճակագրության հետ կապված:

  • Շատ տեղեկություններ. PostgreSQL 9.4-ը տրամադրում է 109 չափումներ՝ վիճակագրության տվյալները դիտելու համար: Այնուամենայնիվ, եթե տվյալների բազան պահպանում է բազմաթիվ աղյուսակներ, սխեմաներ, տվյալների բազաներ, ապա այս բոլոր չափումները պետք է բազմապատկվեն համապատասխան թվով աղյուսակներով, տվյալների բազաներով: Այսինքն՝ ավելի շատ տեղեկություն կա։ Եվ դրա մեջ խեղդվելը շատ հեշտ է:
  • Հաջորդ խնդիրն այն է, որ վիճակագրությունը ներկայացված է հաշվիչներով։ Եթե ​​նայենք այս վիճակագրությանը, ապա կտեսնենք անընդհատ աճող հաշվիչներ։ Եվ եթե վիճակագրության վերակայումից շատ ժամանակ է անցել, մենք միլիարդավոր արժեքներ կտեսնենք։ Իսկ մեզ ոչինչ չեն ասում։
  • Պատմություն չկա։ Եթե ​​ինչ-որ ձախողում ունեք, ինչ-որ բան ընկել է 15-30 րոպե առաջ, դուք չեք կարողանա օգտվել վիճակագրությունից և տեսնել, թե ինչ է տեղի ունեցել 15-30 րոպե առաջ: Սա խնդիր է։
  • PostgreSQL-ում ներկառուցված գործիքի բացակայությունը խնդիր է: Միջուկի մշակողները ոչ մի օգտակար ծրագիր չեն տրամադրում: Նրանք նման բան չունեն։ Ուղղակի տվյալների բազայում վիճակագրություն են տալիս։ Օգտագործի՛ր, խնդրի՛ր նրան, ինչ ուզում ես, հետո արա։
  • Քանի որ PostgreSQL-ում ներկառուցված գործիք չկա, սա այլ խնդիր է առաջացնում: Երրորդ կողմի բազմաթիվ գործիքներ: Յուրաքանչյուր ընկերություն, որն ունի քիչ թե շատ անմիջական ձեռքեր, փորձում է գրել իր ծրագիրը։ Եվ արդյունքում համայնքն ունի բազմաթիվ գործիքներ, որոնցով դուք կարող եք աշխատել վիճակագրության հետ: Իսկ որոշ գործիքների մեջ կան որոշ առանձնահատկություններ, մյուս գործիքներում չկան այլ հնարավորություններ, կամ կան որոշ նոր հնարավորություններ։ Եվ ստեղծվում է մի իրավիճակ, որ դուք պետք է օգտագործեք երկու, երեք կամ չորս գործիքներ, որոնք համընկնում են միմյանց և ունեն տարբեր գործառույթներ: Սա շատ նյարդայնացնում է:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Ի՞նչ է հետևում սրանից։ Կարևոր է, որ կարողանաք ուղղակիորեն վիճակագրություն վերցնել, որպեսզի կախված չլինեք ծրագրերից կամ ինչ-որ կերպ ինքներդ բարելավեք այդ ծրագրերը. ավելացրեք որոշ գործառույթներ՝ ձեր օգուտը ստանալու համար:

Եվ ձեզ անհրաժեշտ է SQL-ի տարրական գիտելիքներ: Վիճակագրությունից որոշ տվյալներ ստանալու համար դուք պետք է կատարեք SQL հարցումներ, այսինքն՝ պետք է իմանաք, թե ինչպես է կատարվում ընտրությունը, միացումը:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Վիճակագրությունը մեզ մի քանի բան է ասում. Դրանք կարելի է բաժանել կատեգորիաների.

  • Առաջին կատեգորիան տվյալների բազայում տեղի ունեցող իրադարձություններն են։ Սա այն դեպքում, երբ տվյալների բազայում տեղի է ունենում ինչ-որ իրադարձություն՝ հարցում, աղյուսակի հասանելիություն, autovacuum, commits, ապա սրանք բոլորը իրադարձություններ են: Այս իրադարձություններին համապատասխան հաշվիչներն ավելացել են։ Եվ մենք կարող ենք հետևել այս իրադարձություններին:
  • Երկրորդ կատեգորիան այնպիսի օբյեկտների հատկություններն են, ինչպիսիք են աղյուսակները, տվյալների բազաները: Նրանք ունեն հատկություններ. Սա սեղանների չափն է: Մենք կարող ենք հետևել աղյուսակների աճին, ինդեքսների աճին։ Մենք կարող ենք տեսնել դինամիկայի փոփոխություններ:
  • Իսկ երրորդ կատեգորիան միջոցառման վրա ծախսված ժամանակն է։ Հարցումը իրադարձություն է: Այն ունի տևողության իր հատուկ չափանիշը: Սկսվեց այստեղ, ավարտվեց այստեղ: Մենք կարող ենք հետևել դրան: Կամ սկավառակից բլոկ կարդալու կամ գրելու ժամանակը: Այս բաները նույնպես հետևվում են:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Վիճակագրության աղբյուրները ներկայացված են հետևյալ կերպ.

  • Համօգտագործվող հիշողության մեջ (համօգտագործվող բուֆերներ) կա ստատիկ տվյալներ այնտեղ տեղադրելու հատված, կան նաև այն հաշվիչներ, որոնք անընդհատ ավելանում են, երբ տեղի են ունենում որոշակի իրադարձություններ, կամ որոշակի պահեր են առաջանում տվյալների բազայի աշխատանքի մեջ:
  • Այս բոլոր հաշվիչները հասանելի չեն օգտատիրոջը և նույնիսկ հասանելի չեն ադմինիստրատորին: Սրանք ցածր մակարդակի բաներ են։ Դրանց մուտք գործելու համար PostgreSQL-ն ապահովում է ինտերֆեյս SQL ֆունկցիաների տեսքով: Մենք կարող ենք ընտրել այս ֆունկցիաները և ստանալ որոշակի չափումներ (կամ չափումների հավաքածու):
  • Այնուամենայնիվ, միշտ չէ, որ հարմար է օգտագործել այս գործառույթները, ուստի գործառույթները հիմք են հանդիսանում դիտումների համար (VIEWs): Սրանք վիրտուալ աղյուսակներ են, որոնք տրամադրում են վիճակագրություն կոնկրետ ենթահամակարգի կամ տվյալների բազայի որոշ իրադարձությունների վերաբերյալ:
  • Այս ներկառուցված դիտումները (VIEWs) հիմնական ինտերֆեյսն են վիճակագրության հետ աշխատելու համար: Դրանք հասանելի են լռելյայն առանց լրացուցիչ կարգավորումների, կարող եք անմիջապես օգտագործել դրանք, դիտել, տեղեկատվություն վերցնել այնտեղից։ Եվ կան նաև ներդրումներ. Ներդրումները պաշտոնական են: Կարող եք տեղադրել postgresql-contrib փաթեթը (օրինակ՝ postgresql94-contrib), բեռնել անհրաժեշտ մոդուլը կոնֆիգուրացիայի մեջ, նշել դրա պարամետրերը, վերագործարկել PostgreSQL-ը և կարող եք օգտագործել այն։ (Նշում. Կախված բաշխումից, ներդրման վերջին տարբերակներում փաթեթը հիմնական փաթեթի մի մասն է).
  • Եվ կան ոչ պաշտոնական ներդրումներ: Նրանք չեն մատակարարվում ստանդարտ PostgreSQL բաշխմամբ: Դրանք կամ պետք է կազմվեն, կամ տեղադրվեն որպես գրադարան: Տարբերակները կարող են շատ տարբեր լինել՝ կախված նրանից, թե ինչ է մտածել այս ոչ պաշտոնական ներդրման մշակողը:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Այս սլայդը ցույց է տալիս բոլոր այն դիտումները (VIEWs) և որոշ գործառույթներ, որոնք հասանելի են PostgreSQL 9.4-ում: Ինչպես տեսնում ենք, դրանք շատ են։ Եվ շատ հեշտ է շփոթվել, եթե դա առաջին անգամ եք զգում:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Այնուամենայնիվ, եթե վերցնենք նախորդ նկարը Как тратится время на PostgreSQL և այս ցանկի հետ համատեղելի, մենք ստանում ենք այս նկարը: Յուրաքանչյուր դիտում (VIEWs) կամ յուրաքանչյուր ֆունկցիա, մենք կարող ենք օգտագործել այս կամ այն ​​նպատակով՝ համապատասխան վիճակագրություն ստանալու համար, երբ մենք աշխատում ենք PostgreSQL-ում: Իսկ ենթահամակարգի աշխատանքի մասին արդեն կարող ենք որոշակի տեղեկություններ ստանալ։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Առաջին բանը, որ մենք կանդրադառնանք, այն է pg_stat_database. Ինչպես տեսնում ենք, սա ներկայացուցչություն է։ Այն պարունակում է բազմաթիվ տեղեկություններ: Ամենատարբեր տեղեկատվություն. Եվ դա շատ օգտակար գիտելիքներ է տալիս այն մասին, թե ինչ է կատարվում տվյալների բազայում:

Ի՞նչ կարող ենք վերցնել այնտեղից: Սկսենք ամենապարզ բաներից։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

select
sum(blks_hit)*100/sum(blks_hit+blks_read) as hit_ratio
from pg_stat_database;

Առաջին բանը, որին մենք կարող ենք նայել, քեշի հարվածների տոկոսն է: Քեշի հարվածների տոկոսը օգտակար չափիչ է: Այն թույլ է տալիս գնահատել, թե որքան տվյալ է վերցված ընդհանուր բուֆերների քեշից և որքան է կարդացվում սկավառակից:

Հասկանալի է, որ որքան շատ քեշի հարվածներ ունենանք, այնքան լավ. Մենք գնահատում ենք այս ցուցանիշը որպես տոկոս: Եվ, օրինակ, եթե մենք ունենք այս քեշի հարվածների տոկոսը 90%-ից ավելի, ապա դա լավ է: Եթե ​​այն իջնի 90%-ից, ապա մենք չունենք բավականաչափ հիշողություն՝ տվյալների տաք գլուխը հիշողության մեջ պահելու համար: Եվ այս տվյալները օգտագործելու համար PostgreSQL-ն ստիպված է լինում մուտք գործել սկավառակ, և դա ավելի դանդաղ է, քան եթե տվյալները կարդացվեն հիշողությունից: Եվ դուք պետք է մտածեք հիշողության ավելացման մասին՝ կա՛մ ավելացնել ընդհանուր բուֆերները, կա՛մ ավելացնել երկաթե հիշողությունը (RAM):

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

select
datname,
(xact_commit*100)/(xact_commit+xact_rollback) as c_ratio,
deadlocks, conflicts,
temp_file, pg_size_pretty(temp_bytes) as temp_size
from pg_stat_database;

Էլ ի՞նչ կարելի է վերցնել այս ներկայացումից։ Դուք կարող եք տեսնել տվյալների բազայում տեղի ունեցող անոմալիաները: Ի՞նչ է ցուցադրված այստեղ: Կան պարտավորություններ, հետադարձումներ, ժամանակավոր ֆայլերի ստեղծում, դրանց չափսեր, փակուղիներ և կոնֆլիկտներ:

Մենք կարող ենք օգտագործել այս հարցումը: Այս SQL-ը բավականին պարզ է: Եվ մենք կարող ենք ինքներս տեսնել այս տվյալները:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Եվ ահա շեմային արժեքները. Մենք նայում ենք պարտավորությունների և հետադարձումների հարաբերակցությանը: Պարտավորությունները գործարքի հաջող հաստատումն է: Հետադարձումները վերադարձն են, այսինքն՝ գործարքը որոշակի աշխատանք է կատարել, լարել է տվյալների բազան, ինչ-որ բան դիտարկել, և հետո տեղի է ունեցել ձախողում, և գործարքի արդյունքները անտեսվում են: այսինքն. անընդհատ աճող հետադարձումների թիվը վատ է: Եվ դուք պետք է ինչ-որ կերպ խուսափեք դրանցից և խմբագրեք կոդը, որպեսզի դա տեղի չունենա:

Հակամարտությունները կապված են կրկնօրինակման հետ: Եվ նրանցից նույնպես պետք է խուսափել։ Եթե ​​դուք ունեք որոշ հարցումներ, որոնք կատարվում են կրկնօրինակի վրա և առաջանում են կոնֆլիկտներ, ապա դուք պետք է վերլուծեք այդ կոնֆլիկտները և տեսնեք, թե ինչ է տեղի ունենում: Մանրամասները կարելի է գտնել տեղեկամատյաններում: Եվ լուծեք կոնֆլիկտները, որպեսզի հավելվածի հարցումներն աշխատեն առանց սխալների:

Փակուղիները նույնպես վատ իրավիճակ են։ Երբ հարցումները մրցում են ռեսուրսների համար, մեկ հարցումը մուտք գործեց մեկ ռեսուրս և վերցրեց կողպեքը, երկրորդ հարցումը մուտք գործեց երկրորդ ռեսուրսը և նաև վերցրեց կողպեքը, և այնուհետև երկու հարցումներն էլ մուտք գործեցին միմյանց ռեսուրսներ և արգելափակվեցին՝ սպասելով, որ հարևանն ազատի կողպեքը: Սա նույնպես խնդրահարույց իրավիճակ է։ Դրանք պետք է լուծվեն հավելվածների վերաշարադրման և ռեսուրսների հասանելիության սերիականացման մակարդակով: Իսկ եթե տեսնում եք, որ ձեր փակուղիներն անընդհատ ավելանում են, ապա պետք է տեղեկամատյաններում նայեք մանրամասներին, վերլուծեք ստեղծված իրավիճակները և տեսնեք, թե որն է խնդիրը։

Ժամանակավոր ֆայլերը (temp_files) նույնպես վատն են: Երբ օգտվողի հարցումը բավարար հիշողություն չունի գործառնական, ժամանակավոր տվյալները տեղավորելու համար, այն սկավառակի վրա ֆայլ է ստեղծում: Եվ բոլոր գործողությունները, որոնք նա կարող էր կատարել հիշողության ժամանակավոր բուֆերում, նա սկսում է կատարել արդեն սկավառակի վրա: Դանդաղ է: Սա մեծացնում է հարցումների կատարման ժամանակը: Իսկ PostgreSQL-ին հարցում ուղարկած հաճախորդը պատասխան կստանա մի փոքր ուշ։ Եթե ​​այս բոլոր գործողությունները կատարվեն հիշողության մեջ, Postgres-ը շատ ավելի արագ կպատասխանի, և հաճախորդը ավելի քիչ կսպասի:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

pg_stat_bgwriter - Այս տեսքը նկարագրում է երկու PostgreSQL ֆոնային ենթահամակարգերի աշխատանքը. checkpointer и background writer.

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Սկսենք, վերլուծենք հսկիչ կետերը, այսպես կոչված. checkpoints. Որոնք են անցակետերը: Անցակետը գործարքների մատյանում տեղ է, որը ցույց է տալիս, որ գրանցամատյանում կատարված տվյալների բոլոր փոփոխությունները հաջողությամբ համաժամացվում են սկավառակի տվյալների հետ: Գործընթացը, կախված աշխատանքային ծանրաբեռնվածությունից և կարգավորումներից, կարող է երկարատև լինել և հիմնականում բաղկացած է կեղտոտ էջերի համաժամանակացումից ընդհանուր բուֆերներում տվյալների ֆայլերի հետ սկավառակի վրա: Ինչի համար է դա? Եթե ​​PostgreSQL-ն անընդհատ մուտք գործեր սկավառակ և այնտեղից տվյալներ վերցներ և յուրաքանչյուր մուտքի վրա տվյալներ գրեր, դա դանդաղ կլիներ: Հետևաբար, PostgreSQL-ն ունի հիշողության հատված, որի չափը կախված է կազմաձևման պարամետրերից։ Postgres-ը գործառնական տվյալներ է հատկացնում այս հիշողության մեջ հետագա մշակման կամ հարցումների համար: Տվյալների փոփոխման հարցումների դեպքում դրանք փոխվում են։ Եվ մենք ստանում ենք տվյալների երկու տարբերակ. Մեկը հիշողության մեջ է, մյուսը՝ սկավառակի վրա։ Եվ պարբերաբար դուք պետք է համաժամանակացնեք այս տվյալները: Մեզ անհրաժեշտ է, որ հիշողության մեջ փոխվածը սինխրոնիզացվի սկավառակի հետ: Սա պահանջում է անցակետեր:

Անցակետն անցնում է ընդհանուր բուֆերներով, նշում է կեղտոտ էջերը, որոնք անհրաժեշտ են անցակետի համար: Այնուհետև այն սկսում է երկրորդ անցումը ընդհանուր բուֆերների միջով: Իսկ այն էջերը, որոնք նշված են անցակետի համար, նա արդեն համաժամացնում է դրանք։ Այսպիսով, տվյալները սինխրոնիզացված են արդեն սկավառակի հետ:

Գոյություն ունեն երկու տեսակի հսկիչ կետեր. Մեկ անցակետը կատարվում է ժամանակի վերջում: Այս անցակետը օգտակար և լավ է. checkpoint_timed. Եվ պահանջով կան անցակետեր. checkpoint required. Նման անցակետը տեղի է ունենում, երբ մենք ունենք տվյալների շատ մեծ գրառում: Մենք գրանցել ենք բազմաթիվ գործարքների մատյաններ: Իսկ PostgreSQL-ը կարծում է, որ պետք է հնարավորինս արագ սինխրոնիզացնել այս ամենը, անցակետ դնել և առաջ շարժվել։

Իսկ եթե նայեիք վիճակագրությանը pg_stat_bgwriter և տեսեք, թե ինչ ունեք checkpoint_req-ը շատ ավելի մեծ է, քան checkpoint_timed-ը, ուրեմն սա վատ է: Ինչու վատ: Սա նշանակում է, որ PostgreSQL-ը մշտական ​​սթրեսի մեջ է, երբ անհրաժեշտ է տվյալներ գրել սկավառակի վրա: Անցակետն ըստ ժամանակաուտի ավելի քիչ սթրեսային է և իրականացվում է ներքին ժամանակացույցի համաձայն և, այսպես ասած, ձգվում է ժամանակի ընթացքում: PostgreSQL-ն ունի աշխատանքը դադարեցնելու և սկավառակի ենթահամակարգը չլարելու հնարավորություն: Սա օգտակար է PostgreSQL-ի համար: Իսկ հարցումները, որոնք կատարվում են անցակետում, սթրես չեն ունենա սկավառակի ենթահամակարգի զբաղված լինելու պատճառով:

Եվ անցակետը կարգավորելու համար կա երեք պարամետր.

  • сheckpoint_segments.

  • сheckpoint_timeout.

  • сheckpoint_competion_target.

Նրանք թույլ են տալիս վերահսկել կառավարման կետերի աշխատանքը: Բայց ես չեմ անդրադառնա դրանց վրա: Նրանց ազդեցությունը առանձին խնդիր է։

Նշում: Զեկույցում դիտարկված 9.4 տարբերակն այլևս տեղին չէ: PostgreSQL-ի ժամանակակից տարբերակներում պարամետրը checkpoint_segments փոխարինվել է պարամետրերով min_wal_size и max_wal_size.

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Հաջորդ ենթահամակարգը ֆոնային գրողն է − background writer. Ինչ է նա անում? Այն անընդհատ աշխատում է անվերջանալի օղակով: Այն սկանավորում է էջերը ընդհանուր բուֆերների մեջ և մաքրում է կեղտոտ էջերը, որոնք գտնում է սկավառակի վրա: Այդպիսով այն օգնում է հսկիչին ավելի քիչ աշխատանք կատարել հսկիչ-անցագրման ժամանակ:

Էլ ինչի՞ համար է նա պետք։ Այն նախատեսում է ընդհանուր բուֆերներում մաքուր էջերի անհրաժեշտությունը, եթե դրանք հանկարծակի պահանջվեն (մեծ քանակությամբ և անմիջապես) տվյալներ տեղավորելու համար: Ենթադրենք, իրավիճակ է ստեղծվել, երբ հարցումը պահանջում է մաքուր էջեր, և դրանք արդեն ընդհանուր բուֆերներում են: Պոստգրես backend նա ուղղակի վերցնում է դրանք ու օգտագործում, ինքը պարտավոր չէ ոչինչ մաքրել։ Բայց եթե հանկարծ այդպիսի էջեր չլինեն, հետնամասը կանգ է առնում և սկսում է որոնել էջեր՝ դրանք սկավառակի վրա դնելու և իր կարիքների համար վերցնելու համար, ինչը բացասաբար է անդրադառնում ներկայումս կատարվող հարցումի ժամանակի վրա: Եթե ​​տեսնում եք, որ պարամետր ունեք maxwritten_clean մեծ, սա նշանակում է, որ ֆոնային գրողը չի կատարում իր աշխատանքը, և դուք պետք է մեծացնեք պարամետրերը bgwriter_lru_maxpagesորպեսզի մեկ ցիկլով ավելի շատ աշխատանք կատարի, ավելի շատ էջեր մաքրի։

Եվ մեկ այլ շատ օգտակար ցուցանիշ է buffers_backend_fsync. Backend-ները չեն կատարում fsync, քանի որ այն դանդաղ է: Նրանք անցնում են fsync մինչև IO stack checkpointer-ը: Անցակետն ունի իր սեփական հերթը, այն պարբերաբար մշակում է fsync-ը և հիշողության մեջ էջերը համաժամեցնում սկավառակի վրա գտնվող ֆայլերի հետ: Եթե ​​հսկիչի հերթը մեծ է և լի, ապա backend-ը ստիպված է ինքնուրույն կատարել fsync, և դա դանդաղեցնում է հետին պլանը:, այսինքն՝ հաճախորդը պատասխան կստանա ավելի ուշ, քան կարող էր։ Եթե ​​տեսնում եք, որ այս արժեքը զրոյից մեծ է, ապա սա արդեն խնդիր է և դուք պետք է ուշադրություն դարձնեք ֆոնային գրողի պարամետրերին և նաև գնահատեք սկավառակի ենթահամակարգի կատարումը:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Նշում: _Հետևյալ տեքստը նկարագրում է կրկնօրինակման հետ կապված վիճակագրական տեսակետները: Դիտումների և գործառույթների անունների մեծ մասը վերանվանվել է Postgres 10-ում: Վերանվանումների էությունը փոխարինվելն էր: xlog մասին wal и location մասին lsn ֆունկցիաների/դիտումների անուններում և այլն: Հատուկ օրինակ, գործառույթ pg_xlog_location_diff() վերանվանվել է pg_wal_lsn_diff()._

Մենք այստեղ էլ շատ ունենք։ Բայց մեզ անհրաժեշտ են միայն տեղանքի հետ կապված իրեր։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Եթե ​​տեսնում ենք, որ բոլոր արժեքները հավասար են, ապա սա իդեալական է, և կրկնօրինակը հետ չի մնում վարպետից։

Այս տասնվեցական դիրքն այստեղ գործարքների մատյանում եղած դիրքն է: Այն անընդհատ ավելանում է, եթե տվյալների բազայում որոշակի ակտիվություն կա՝ ներդիրներ, ջնջումներ և այլն։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

сколько записано xlog в байтах
$ select
pg_xlog_location_diff(pg_current_xlog_location(),'0/00000000');
лаг репликации в байтах
$ select
client_addr,
pg_xlog_location_diff(pg_current_xlog_location(), replay_location)
from pg_stat_replication;
лаг репликации в секундах
$ select
extract(epoch from now() - pg_last_xact_replay_timestamp());

Եթե ​​այս բաները տարբեր են, ուրեմն ինչ-որ ուշացում կա: Lag-ը կրկնօրինակի հետաձգումն է վարպետից, այսինքն՝ տվյալները տարբերվում են սերվերների միջև:

Հետաձգման երեք պատճառ կա.

  • Դա սկավառակի ենթահամակարգն է, որը չի կարող կառավարել ֆայլերի համաժամացման գրությունները:
  • Սրանք ցանցի հնարավոր սխալներ են կամ ցանցի ծանրաբեռնվածություն, երբ տվյալները ժամանակ չունեն կրկնօրինակին հասնելու և այն չի կարող վերարտադրել այն:
  • Եվ պրոցեսորը: Պրոցեսորը շատ հազվադեպ դեպք է։ Եվ ես դա տեսել եմ երկու կամ երեք անգամ, բայց դա նույնպես կարող է պատահել:

Եվ ահա երեք հարցումներ, որոնք թույլ են տալիս օգտվել վիճակագրությունից: Մենք կարող ենք գնահատել, թե որքան է գրանցված մեր գործարքների մատյանում: Նման գործառույթ կա pg_xlog_location_diff և մենք կարող ենք գնահատել կրկնօրինակման հետաձգումը բայթերով և վայրկյաններով: Դրա համար մենք օգտագործում ենք նաև այս տեսքի արժեքը (VIEWs):

Նշում: _pg_xlog_location-ի փոխարենdiff() ֆունկցիան, կարող եք օգտագործել Subtract օպերատորը և հանել մի տեղ մյուսից: Հարմարավետ.

Մի ուշացումով, որը վայրկյաններով է, կա մեկ պահ. Եթե ​​վարպետի վրա ակտիվություն չկա, գործարքը եղել է մոտ 15 րոպե առաջ, և ակտիվություն չկա, և եթե նայենք այս հետաձգմանը ռեպլիկի վրա, ապա կտեսնենք 15 րոպեի հետաձգում: Սա արժե հիշել. Եվ դա կարող է հանգեցնել անհանգստության, երբ դուք դիտում եք այս ուշացումը:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

pg_stat_all_tables-ը ևս մեկ օգտակար տեսակետ է: Այն ցույց է տալիս վիճակագրությունը աղյուսակների վրա: Երբ տվյալների բազայում ունենք աղյուսակներ, դրա հետ ինչ-որ ակտիվություն կա, որոշ գործողություններ, մենք կարող ենք այս տեղեկատվությունը ստանալ այս տեսքից:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

select
relname,
pg_size_pretty(pg_relation_size(relname::regclass)) as size,
seq_scan, seq_tup_read,
seq_scan / seq_tup_read as seq_tup_avg
from pg_stat_user_tables
where seq_tup_read > 0 order by 3,4 desc limit 5;

Առաջին բանը, որին մենք կարող ենք նայել, աղյուսակի հաջորդական սկանավորումն է: Այս հատվածներից հետո թիվն ինքնին անպայմանորեն վատ չէ և չի նշանակում, որ մենք արդեն ինչ-որ բան պետք է անենք:

Այնուամենայնիվ, կա երկրորդ չափանիշը՝ seq_tup_read: Սա հաջորդական սկանավորումից վերադարձված տողերի թիվն է: Եթե ​​միջին թիվը գերազանցում է 1-ը, 000-ը, 10-ը, 000-ը, ապա սա արդեն ցուցիչ է, որ ձեզ հարկավոր է ինչ-որ տեղ ինդեքս ստեղծել, որպեսզի մուտքերը լինեն ըստ ինդեքսների, կամ հնարավոր է օպտիմալացնել հարցումները, որոնք օգտագործում են նման հաջորդական սկանավորումներ, որպեսզի դա տեղի չի ունենում, եղել է.

Պարզ օրինակ՝ ասենք մեծ OFFSET-ով և LIMIT-ով խնդրանքն արժե: Օրինակ, աղյուսակի 100 տողերը սկանավորվում են և դրանից հետո վերցվում են 000 պահանջվող տողերը, իսկ նախորդ սկանավորված տողերը հանվում են: Սա նույնպես վատ դեպք է։ Իսկ նման հարցումները պետք է օպտիմալացվեն։ Եվ ահա այսպիսի պարզ SQL հարցում, որի վրա կարող եք տեսնել այն և գնահատել ստացված թվերը։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

select
relname,
pg_size_pretty(pg_total_relation_size(relname::regclass)) as
full_size,
pg_size_pretty(pg_relation_size(relname::regclass)) as
table_size,
pg_size_pretty(pg_total_relation_size(relname::regclass) -
pg_relation_size(relname::regclass)) as index_size
from pg_stat_user_tables
order by pg_total_relation_size(relname::regclass) desc limit 10;

Սեղանի չափերը կարելի է ձեռք բերել նաև այս աղյուսակի և լրացուցիչ գործառույթների միջոցով pg_total_relation_size(), pg_relation_size().

Ընդհանուր առմամբ, կան մետահրամաններ dt и di, որը կարող եք օգտագործել PSQL-ում, ինչպես նաև տեսնել աղյուսակի և ինդեքսների չափերը:

Այնուամենայնիվ, գործառույթների օգտագործումն օգնում է մեզ նայել աղյուսակների չափերը՝ նույնիսկ հաշվի առնելով ինդեքսները, կամ առանց ինդեքսների հաշվի առնելու, և արդեն կատարել որոշ գնահատականներ՝ հիմնվելով տվյալների բազայի աճի վրա, այսինքն՝ ինչպես է այն աճում մեզ հետ, ինչ ինտենսիվություն, և արդեն որոշ եզրակացություններ արեք չափերի օպտիմալացման վերաբերյալ:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Գրել գործունեություն. Ի՞նչ է ռեկորդը: Եկեք նայենք վիրահատությանը UPDATE - աղյուսակում տողերի թարմացման գործողությունը: Փաստորեն, թարմացումը երկու գործողություն է (կամ նույնիսկ ավելին): Սա նոր տողի տարբերակ է տեղադրում և հին շարքի տարբերակը հնացած նշում: Ավելի ուշ ավտովակուումը կգա և կմաքրի գծերի այս հնացած տարբերակները, նշեք այս վայրը որպես հասանելի նորից օգտագործման համար:

Բացի այդ, թարմացումը միայն աղյուսակը թարմացնելու մասին չէ: Դա դեռ ինդեքսի թարմացում է: Եթե ​​աղյուսակում ունեք շատ ինդեքսներ, ապա թարմացման դեպքում բոլոր ինդեքսները, որոնց մասնակցում են հարցումում թարմացված դաշտերը, նույնպես պետք է թարմացվեն։ Այս ինդեքսները կունենան նաև հնացած տողերի տարբերակներ, որոնք պետք է մաքրվեն:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

select
s.relname,
pg_size_pretty(pg_relation_size(relid)),
coalesce(n_tup_ins,0) + 2 * coalesce(n_tup_upd,0) -
coalesce(n_tup_hot_upd,0) + coalesce(n_tup_del,0) AS total_writes,
(coalesce(n_tup_hot_upd,0)::float * 100 / (case when n_tup_upd > 0
then n_tup_upd else 1 end)::float)::numeric(10,2) AS hot_rate,
(select v[1] FROM regexp_matches(reloptions::text,E'fillfactor=(\d+)') as
r(v) limit 1) AS fillfactor
from pg_stat_all_tables s
join pg_class c ON c.oid=relid
order by total_writes desc limit 50;

Եվ իր դիզայնի շնորհիվ UPDATE-ը ծանրաբեռնված գործողություն է: Բայց դրանք կարելի է ավելի հեշտ դարձնել: Ուտել hot updates. Դրանք հայտնվել են PostgreSQL 8.3 տարբերակում: Իսկ սա ի՞նչ է։ Սա թեթև թարմացում է, որը չի առաջացնում ինդեքսների վերակառուցում: Այսինքն՝ մենք թարմացրել ենք գրառումը, բայց թարմացվել է միայն էջի գրառումը (որը պատկանում է աղյուսակին), և ինդեքսները դեռ մատնանշում են էջի նույն գրառումը։ Մի քիչ նման հետաքրքիր աշխատանքի տրամաբանություն կա, երբ վակուումը գալիս է, ուրեմն ունի այս շղթաները hot վերակառուցվում է, և ամեն ինչ շարունակում է աշխատել առանց ինդեքսների թարմացման, և ամեն ինչ տեղի է ունենում ռեսուրսների ավելի քիչ վատնման դեպքում:

Եվ երբ դուք ունեք n_tup_hot_upd մեծ, շատ լավ է: Սա նշանակում է, որ գերակշռում են թեթև թարմացումները, և դա մեզ համար ավելի էժան է ռեսուրսների առումով, և ամեն ինչ լավ է:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

ALTER TABLE table_name SET (fillfactor = 70);

Ինչպես բարձրացնել ծավալը hot updateօվ? Մենք կարող ենք օգտագործել fillfactor. Այն որոշում է վերապահված ազատ տարածության չափը աղյուսակում էջը INSERT-ների միջոցով լրացնելիս: Երբ ներդիրները գնում են աղյուսակ, դրանք ամբողջությամբ լրացնում են էջը, դրա մեջ դատարկ տեղ չեն թողնում։ Այնուհետև ընդգծվում է նոր էջ: Տվյալները նորից լրացվում են։ Եվ սա լռելյայն վարքագիծն է, fillfactor = 100%:

Մենք կարող ենք լրացման գործակիցը սահմանել 70%: Այսինքն՝ ներդիրներով նոր էջ է հատկացվել, բայց լրացվել է էջի միայն 70%-ը։ Իսկ մեզ ռեզերվում է մնացել 30 տոկոսը։ Երբ դուք պետք է թարմացնեք, դա, ամենայն հավանականությամբ, տեղի կունենա նույն էջում, և շարքի նոր տարբերակը կտեղավորվի նույն էջում: Եվ hot_update-ը կկատարվի։ Սա հեշտացնում է աղյուսակների վրա գրելը:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

select c.relname,
current_setting('autovacuum_vacuum_threshold') as av_base_thresh,
current_setting('autovacuum_vacuum_scale_factor') as av_scale_factor,
(current_setting('autovacuum_vacuum_threshold')::int +
(current_setting('autovacuum_vacuum_scale_factor')::float * c.reltuples))
as av_thresh,
s.n_dead_tup
from pg_stat_user_tables s join pg_class c ON s.relname = c.relname
where s.n_dead_tup > (current_setting('autovacuum_vacuum_threshold')::int
+ (current_setting('autovacuum_vacuum_scale_factor')::float * c.reltuples));

Ավտովակուումային հերթ. Autovacuum-ն այնպիսի ենթահամակարգ է, որի համար շատ քիչ վիճակագրություն կա PostgreSQL-ում: Մենք կարող ենք տեսնել միայն pg_stat_activity-ի աղյուսակներում, թե որքան վակուում ունենք այս պահին: Այնուամենայնիվ, շատ դժվար է հասկանալ, թե քանի սեղան ունի այն հերթում շարժման մեջ:

Նշում: _ Postgres 10-ից ի վեր վակուումային վակուումին հետևելու հետ կապված իրավիճակը շատ է բարելավվել. հայտնվել է pg_stat_progress տեսքըվակուում, որը մեծապես հեշտացնում է ավտովակուումային մոնիտորինգի հարցը:

Մենք կարող ենք օգտագործել այս պարզեցված հարցումը: Եվ մենք կարող ենք տեսնել, թե երբ պետք է ստեղծվի վակուումը: Բայց ինչպե՞ս և ե՞րբ պետք է սկսվի վակուումը: Սրանք լարերի հին տարբերակներն են, որոնց մասին ավելի վաղ խոսեցի: Թարմացումը տեղի է ունեցել, շարքի նոր տարբերակը տեղադրվել է: Հայտնվել է տողի հնացած տարբերակը։ Աղյուսակ pg_stat_user_tables կա նման պարամետր n_dead_tup. Այն ցույց է տալիս «մեռած» շարքերի քանակը: Եվ հենց որ մեռած տողերի թիվը որոշակի շեմից ավելի դառնա, սեղանի վրա կգա ավտովակում։

Իսկ ինչպե՞ս է հաշվարկվում այս շեմը։ Սա աղյուսակի տողերի ընդհանուր թվի շատ կոնկրետ տոկոսն է: Պարամետր կա autovacuum_vacuum_scale_factor. Այն սահմանում է տոկոսը: Ասենք 10% + կա լրացուցիչ 50 տող բազային շեմ։ Իսկ ի՞նչ է լինում։ Երբ մենք ունենք ավելի շատ մեռած տողեր, քան աղյուսակի բոլոր տողերի «10% + 50»-ը, մենք աղյուսակը դնում ենք ավտովակուումի վրա:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

select c.relname,
current_setting('autovacuum_vacuum_threshold') as av_base_thresh,
current_setting('autovacuum_vacuum_scale_factor') as av_scale_factor,
(current_setting('autovacuum_vacuum_threshold')::int +
(current_setting('autovacuum_vacuum_scale_factor')::float * c.reltuples))
as av_thresh,
s.n_dead_tup
from pg_stat_user_tables s join pg_class c ON s.relname = c.relname
where s.n_dead_tup > (current_setting('autovacuum_vacuum_threshold')::int
+ (current_setting('autovacuum_vacuum_scale_factor')::float * c.reltuples));

Այնուամենայնիվ, կա մեկ կետ. Պարամետրերի հիմնական շեմերը av_base_thresh и av_scale_factor կարող է նշանակվել անհատապես: Եվ, համապատասխանաբար, սեղանի համար շեմը կլինի ոչ թե գլոբալ, այլ անհատական։ Հետեւաբար, հաշվարկելու համար այնտեղ անհրաժեշտ է օգտագործել հնարքներ և հնարքներ: Եվ եթե ձեզ հետաքրքրում է, կարող եք դիտել Avito-ի մեր գործընկերների փորձը (սլայդի հղումն անվավեր է և թարմացվել է տեքստում):

համար են գրել munin pluginորը հաշվի է առնում այս բաները: Երկու սավանի վրա ոտքի ծածկոց կա։ Բայց նա ճիշտ է համարում և բավականին արդյունավետ թույլ է տալիս գնահատել, թե որտեղ է մեզ շատ վակուում անհրաժեշտ սեղանների համար, որտեղ քիչ է։

Ի՞նչ կարող ենք անել դրա դեմ: Եթե ​​մենք երկար հերթ ունենք, և ավտովակուումը չի կարողանում հաղթահարել, ապա մենք կարող ենք ավելացնել վակուումային աշխատողների թիվը կամ պարզապես վակուումը դարձնել ավելի ագրեսիվ:այնպես, որ այն ավելի շուտ սկսի, սեղանը մշակում է փոքր կտորներով: Եվ այդպիսով հերթը կնվազի։ - Այստեղ գլխավորը սկավառակների ծանրաբեռնվածության մոնիտորինգն է, քանի որ. Վակուումային բանն անվճար չէ, թեև SSD/NVMe սարքերի հայտնվելով խնդիրն ավելի քիչ նկատելի է դարձել։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

pg_stat_all_indexes-ը ինդեքսների վիճակագրությունն է: Նա մեծ չէ: Եվ դրանից մենք կարող ենք տեղեկատվություն ստանալ ինդեքսների օգտագործման մասին։ Եվ օրինակ, մենք կարող ենք որոշել, թե որ ինդեքսներն ունենք լրացուցիչ։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Ինչպես արդեն ասացի, Թարմացումը միայն աղյուսակների թարմացում չէ, այն նաև ինդեքսների թարմացում է: Համապատասխանաբար, եթե աղյուսակում ունենք շատ ինդեքսներ, ապա աղյուսակի տողերը թարմացնելիս անհրաժեշտ է թարմացնել նաև ինդեքսավորված դաշտերի ինդեքսները, և եթե մենք ունենք չօգտագործված ինդեքսներ, որոնց համար ինդեքսի սկանավորում չկա, ապա դրանք մեզ հետ կախված են որպես բալաստ: Եվ դուք պետք է ձերբազատվեք դրանցից: Սրա համար մեզ դաշտ է պետք idx_scan. Մենք պարզապես նայում ենք ինդեքսի սկանավորման քանակին: Եթե ​​ինդեքսներն ունեն զրոյական սկանավորում վիճակագրության պահպանման համեմատաբար երկար ժամանակահատվածում (առնվազն 2-3 շաբաթ), ապա, ամենայն հավանականությամբ, դրանք վատ ցուցանիշներ են, մենք պետք է ազատվենք դրանցից:

Նշում: Հոսքային վերարտադրության կլաստերների դեպքում չօգտագործված ինդեքսներ որոնելիս պետք է ստուգել կլաստերի բոլոր հանգույցները, քանի որ. վիճակագրությունը գլոբալ չէ, և եթե ինդեքսը չի օգտագործվում վարպետի վրա, ապա այն կարող է օգտագործվել կրկնօրինակների վրա (եթե կա ծանրաբեռնվածություն):

Երկու հղում.

https://github.com/dataegret/pg-utils/blob/master/sql/low_used_indexes.sql

http://www.databasesoup.com/2014/05/new-finding-unused-indexes-query.html

Սրանք ավելի առաջադեմ հարցման օրինակներ են, թե ինչպես փնտրել չօգտագործված ինդեքսները:

Երկրորդ հղումը բավականին հետաքրքիր հարցում է։ Դրանում շատ ոչ տրիվիալ տրամաբանություն կա։ Ես խորհուրդ եմ տալիս վերանայման համար:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Էլ ի՞նչ պետք է ամփոփել ինդեքսներով։

  • Չօգտագործված ցուցանիշները վատ են:

  • Նրանք տեղ են գրավում:

  • Դանդաղեցրեք թարմացման գործողությունները:

  • Լրացուցիչ աշխատանք վակուումի համար:

Եթե ​​մենք հեռացնենք չօգտագործված ինդեքսները, ապա մենք միայն ավելի լավ կդարձնենք տվյալների բազան:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Հաջորդ տեսակետն է pg_stat_activity. Սա կոմունալ ծառայության անալոգն է ps, միայն PostgreSQL-ում։ Եթե ps«Օհ, դուք հետևում եք օպերացիոն համակարգի գործընթացներին, ապա pg_stat_activity ձեզ ցույց կտա գործունեությունը PostgreSQL-ի ներսում:

Ի՞նչ կարող ենք վերցնել այնտեղից:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

select
count(*)*100/(select current_setting('max_connections')::int)
from pg_stat_activity;

Մենք կարող ենք տեսնել ընդհանուր գործունեությունը, որը տեղի է ունենում տվյալների բազայում: Մենք կարող ենք նոր տեղակայում. Այնտեղ ամեն ինչ պայթեց, նոր կապերը չեն ընդունվում, հավելվածում սխալներ են թափվում։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

select
client_addr, usename, datname, count(*)
from pg_stat_activity group by 1,2,3 order by 4 desc;

Մենք կարող ենք կատարել այսպիսի հարցում և տեսնել կապերի ընդհանուր տոկոսը կապի առավելագույն սահմանաչափի համեմատ և տեսնել, թե ով ենք մենք ամենաշատ կապերը: Եվ այս դեպքում մենք տեսնում ենք այդ օգտագործողին cron_role բացել է 508 միացում։ Եվ նրա հետ ինչ-որ բան պատահեց. Դուք պետք է զբաղվեք դրա հետ և տեսնեք: Եվ միանգամայն հնարավոր է, որ սա կապերի ինչ-որ անոմալ քանակություն է։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Եթե ​​մենք ունենք OLTP բեռնվածություն, հարցումները պետք է լինեն արագ, շատ արագ, և չպետք է լինեն երկար հարցումներ: Այնուամենայնիվ, եթե կան երկար խնդրանքներ, ապա կարճաժամկետ կտրվածքով անհանգստանալու ոչինչ չկա, բայց Երկարաժամկետ հեռանկարում, երկար հարցումները վնասում են տվյալների բազան, դրանք մեծացնում են աղյուսակների bloat ազդեցությունը, երբ աղյուսակի մասնատումը տեղի է ունենում: Ե՛վ փքվածությունը, և՛ երկար հարցումները պետք է հեռացվեն:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

select
client_addr, usename, datname,
clock_timestamp() - xact_start as xact_age,
clock_timestamp() - query_start as query_age,
query
from pg_stat_activity order by xact_start, query_start;

Խնդրում ենք նկատի ունենալ. նման խնդրանքով մենք կարող ենք սահմանել երկար հարցումներ և գործարքներ: Մենք օգտագործում ենք գործառույթը clock_timestamp() աշխատանքային ժամանակը որոշելու համար. Երկար խնդրանքներ, որոնք մենք գտել ենք, մենք կարող ենք հիշել դրանք, կատարել դրանք explain, նայեք պլաններին և ինչ-որ կերպ օպտիմալացրեք: Մենք նկարահանում ենք ընթացիկ երկար խնդրանքները և շարունակում ենք ապրել:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

select * from pg_stat_activity where state in
('idle in transaction', 'idle in transaction (aborted)';

Վատ գործարքները անգործության են մատնված գործարքների ժամանակ և անգործուն են գործարքների (վիժեցված) գործարքներում:

Ինչ է դա նշանակում? Գործարքներն ունեն մի քանի վիճակ: Եվ այս պետություններից մեկը կարող է ցանկացած պահի վերցնել: Նահանգները սահմանելու դաշտ կա state այս տեսակետում. Եվ մենք դա օգտագործում ենք պետությունը որոշելու համար։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

select * from pg_stat_activity where state in
('idle in transaction', 'idle in transaction (aborted)';

Եվ, ինչպես ասացի վերևում, այս երկու պետությունները անգործուն գործարքի և անգործության գործարքի մեջ (վիժեցված) վատ են: Ինչ է դա? Սա այն դեպքում, երբ հավելվածը բացեց գործարք, կատարեց որոշ գործողություններ և անցավ իր գործին: Գործարքը մնում է բաց։ Այն կախված է, դրա մեջ ոչինչ չի պատահում, այն միացում է պահանջում, կողպվում է փոփոխված շարքերում և, հնարավոր է, դեռ մեծացնում է այլ աղյուսակների փքվածությունը՝ շնորհիվ Postrges գործարքային շարժիչի ճարտարապետության: Եվ նման գործարքները նույնպես պետք է գնդակահարվեն, քանի որ դրանք ընդհանրապես վնասակար են ամեն դեպքում։

Եթե ​​տեսնում եք, որ ձեր տվյալների բազայում դրանցից ավելի քան 5-10-20 ունեք, ապա պետք է անհանգստանաք և սկսեք ինչ-որ բան անել նրանց հետ:

Այստեղ մենք օգտագործում ենք նաև հաշվարկման ժամանակը clock_timestamp(). Մենք նկարահանում ենք գործարքներ, օպտիմիզացնում ենք հավելվածը։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Ինչպես ասացի վերևում, կողպեքներն այն են, երբ երկու կամ ավելի գործարքներ մրցում են ռեսուրսների մեկ կամ խմբի համար: Սրա համար մենք դաշտ ունենք waiting բուլյան արժեքով true կամ false.

Ճիշտ է, սա նշանակում է, որ գործընթացը սպասում է, ինչ-որ բան պետք է անել: Երբ պրոցեսը սպասում է, ապա այդ գործընթացը նախաձեռնած հաճախորդը նույնպես սպասում է: Բրաուզերի հաճախորդը նստում է և նույնպես սպասում:

Նշում: _Սկսած Postgres 9.6-ից՝ դաշտ waiting հեռացվել և փոխարինվել է ևս երկու տեղեկատվական դաշտով wait_event_type и wait_event._

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Ինչ անել? Եթե ​​երկար ժամանակ ճիշտ եք տեսնում, ուրեմն պետք է ձերբազատվեք նման խնդրանքներից։ Մենք ուղղակի նկարահանում ենք նման գործարքներ։ Մենք գրում ենք մշակողներին այն, ինչ պետք է ինչ-որ կերպ օպտիմալացնել, որպեսզի ռեսուրսների համար մրցավազք չլինի: Եվ հետո մշակողները օպտիմիզացնում են հավելվածը, որպեսզի դա տեղի չունենա։

Եվ ծայրահեղ, բայց պոտենցիալ ոչ մահացու դեպք է փակուղիների առաջացում. Երկու գործարքներ թարմացրել են երկու ռեսուրսներ, այնուհետև նորից մուտք են գործում դրանք՝ արդեն հակառակ ռեսուրսների։ PostgreSQL-ն այս դեպքում վերցնում և անջատում է գործարքը, որպեսզի մյուսը կարողանա շարունակել աշխատել: Սա փակուղային իրավիճակ է, և նա ինքն իրեն չի հասկանում։ Ուստի PostgreSQL-ն ստիպված է ծայրահեղ միջոցների դիմել։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

https://github.com/lesovsky/uber-scripts/blob/master/postgresql/sql/c4_06_show_locked_queries.sql

https://github.com/lesovsky/uber-scripts/blob/master/postgresql/sql/show_locked_queries_95.sql

https://github.com/lesovsky/uber-scripts/blob/master/postgresql/sql/show_locked_queries_96.sql

http://big-elephants.com/2013-09/exploring-query-locks-in-postgres/

Եվ ահա երկու հարցումներ, որոնք թույլ են տալիս հետևել կողպեքներին: Մենք օգտագործում ենք տեսարանը pg_locks, որը թույլ է տալիս հետևել ծանր կողպեքներին:

Իսկ առաջին հղումը հենց հարցման տեքստն է։ Դա բավականին երկար է:

Իսկ երկրորդ հղումը կողպեքների մասին հոդված է։ Օգտակար է կարդալ, շատ հետաքրքիր է։

Այսպիսով, ինչ ենք մենք տեսնում: Մենք տեսնում ենք երկու խնդրանք. Գործարքի հետ ALTER TABLE արգելափակող գործարք է: Այն սկսվեց, բայց չավարտվեց, և հավելվածը, որը տեղադրեց այս գործարքը, ինչ-որ տեղ այլ բաներ է անում: Իսկ երկրորդ հարցումը թարմացումն է։ Այն սպասում է, որ փոփոխվող աղյուսակը ավարտվի, նախքան իր աշխատանքը շարունակելը:

Այսպես մենք կարող ենք պարզել, թե ով ում է փակել, ով ում է պահում, և մենք կարող ենք հետագայում դրանով զբաղվել։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Հաջորդ մոդուլն է pg_stat_statements. Ինչպես ասացի, դա մոդուլ է: Այն օգտագործելու համար անհրաժեշտ է բեռնել նրա գրադարանը կոնֆիգուրացիայի մեջ, վերագործարկել PostgreSQL-ը, տեղադրել մոդուլը (մեկ հրամանով), այնուհետև մենք կունենանք նոր տեսք։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Cреднее время запроса в милисекундах
$ select (sum(total_time) / sum(calls))::numeric(6,3)
from pg_stat_statements;

Самые активно пишущие (в shared_buffers) запросы
$ select query, shared_blks_dirtied
from pg_stat_statements
where shared_blks_dirtied > 0 order by 2 desc;

Ի՞նչ կարող ենք վերցնել այնտեղից: Եթե ​​խոսենք պարզ բաների մասին, կարող ենք վերցնել հարցման կատարման միջին ժամանակը: Ժամանակն աճում է, ինչը նշանակում է, որ PostgreSQL-ը դանդաղ է արձագանքում, և ինչ-որ բան պետք է անել:

Մենք կարող ենք տեսնել տվյալների բազայում գրավոր ամենաակտիվ գործարքները, որոնք փոխում են տվյալները ընդհանուր բուֆերներում: Տեսեք, թե ով է այնտեղ թարմացնում կամ ջնջում տվյալները:

Եվ մենք կարող ենք պարզապես նայել այս հարցումների տարբեր վիճակագրություն:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

https://github.com/dataegret/pg-utils/blob/master/sql/global_reports/query_stat_total.sql

Մենք pg_stat_statements օգտագործվում է հաշվետվություններ պատրաստելու համար: Մենք վիճակագրությունը զրոյացնում ենք օրը մեկ անգամ: Եկեք այն կուտակենք։ Հաջորդ անգամ վիճակագրությունը վերականգնելուց առաջ մենք հաշվետվություն ենք պատրաստում: Ահա զեկույցի հղումը: Դուք կարող եք դիտել այն։

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Ինչ ենք մենք անում? Մենք հաշվարկում ենք ընդհանուր վիճակագրությունը բոլոր հարցումների համար: Այնուհետև յուրաքանչյուր հարցման համար մենք հաշվում ենք նրա անհատական ​​ներդրումը այս ընդհանուր վիճակագրության մեջ:

Իսկ ի՞նչ կարող ենք տեսնել։ Մենք կարող ենք տեսնել որոշակի տեսակի բոլոր հարցումների կատարման ընդհանուր ժամանակը բոլոր մյուս հարցումների ֆոնին: Մենք կարող ենք դիտարկել CPU-ի և I/O-ի օգտագործումը ընդհանուր պատկերի հետ կապված: Եվ արդեն օպտիմալացնել այս հարցումները: Մենք այս զեկույցի հիման վրա կառուցում ենք լավագույն հարցումները և արդեն մտածելու տեղիք ենք տալիս, թե ինչ օպտիմալացնել:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Ի՞նչ ունենք կուլիսներում. Դեռևս կան մի քանի հայտարարություններ, որոնք ես չեմ քննարկել, քանի որ ժամանակը սահմանափակ է:

Կա pgstattuple նաև լրացուցիչ մոդուլ է ստանդարտ ներդրումների փաթեթից: Այն թույլ է տալիս գնահատել bloat սեղաններ, այսպես կոչված. սեղանի մասնատում. Իսկ եթե մասնատումը մեծ է, պետք է հեռացնել այն, օգտագործել տարբեր գործիքներ։ Եվ գործառույթ pgstattuple աշխատում է երկար ժամանակ: Եվ որքան շատ սեղաններ, այնքան երկար այն կաշխատի:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Հաջորդ ներդրումն է pg_buffercache. Այն թույլ է տալիս ստուգել ընդհանուր բուֆերները՝ որքան ինտենսիվ և ինչ աղյուսակների համար են օգտագործվում բուֆերային էջերը: Եվ դա պարզապես թույլ է տալիս դիտել ընդհանուր բուֆերները և գնահատել, թե ինչ է կատարվում այնտեղ:

Հաջորդ մոդուլն է pgfincore. Այն թույլ է տալիս համակարգային զանգի միջոցով կատարել սեղանի ցածր մակարդակի գործողություններ mincore(), այսինքն՝ այն թույլ է տալիս բեռնել աղյուսակը ընդհանուր բուֆերներում կամ բեռնաթափել այն: Եվ դա թույլ է տալիս, ի թիվս այլ բաների, ստուգել օպերացիոն համակարգի էջի քեշը, այսինքն, թե որքան է աղյուսակը զբաղեցնում էջի քեշում, ընդհանուր բուֆերներում, և պարզապես թույլ է տալիս գնահատել սեղանի ծանրաբեռնվածությունը:

Հաջորդ մոդուլն է pg_stat_kcache. Այն նաև օգտագործում է համակարգային զանգը getrusage(). Եվ այն կատարում է հարցումը կատարելուց առաջ և հետո: Եվ ստացված վիճակագրության մեջ այն թույլ է տալիս մեզ գնահատել, թե որքան է ծախսվել մեր հարցումը սկավառակի I/O-ի վրա, այսինքն՝ ֆայլային համակարգի հետ գործառնությունների վրա և դիտարկել պրոցեսորի օգտագործումը: Այնուամենայնիվ, մոդուլը երիտասարդ է (khe-khe) և իր աշխատանքի համար այն պահանջում է PostgreSQL 9.4 և pg_stat_statements, որոնք ես ավելի վաղ նշեցի:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

  • Վիճակագրություն օգտագործելու ունակությունը օգտակար է: Ձեզ հարկավոր չէ երրորդ կողմի ծրագրակազմ: Դուք կարող եք նայել, տեսնել, ինչ-որ բան անել, կատարել:

  • Վիճակագրություն օգտագործելը հեշտ է, այն պարզ SQL է: Խնդրանք հավաքեցիր, կազմեցիր, ուղարկեցիր, նայեցիր։

  • Վիճակագրությունը օգնում է պատասխանել հարցերին: Եթե ​​հարցեր ունեք, դիմում եք վիճակագրության՝ նայեք, եզրակացություններ արեք, վերլուծեք արդյունքները։

  • Եվ փորձ. Շատ հարցումներ, շատ տվյալներ: Դուք միշտ կարող եք օպտիմալացնել որոշ առկա հարցումներ: Դուք կարող եք կատարել խնդրանքի ձեր տարբերակը, որը ձեզ ավելի հարմար է, քան բնօրինակը և օգտագործել այն:

Խորը սուզվել PostgreSQL-ի ներքին վիճակագրության մեջ: Ալեքսեյ Լեսովսկի

Սայլակ

Վավեր հղումներ, որոնք գտնվել են հոդվածում, որոնց հիման վրա, եղել են զեկույցում։

Հեղինակը գրել ավելին
https://dataegret.com/news-blog (eng)

Վիճակագրության կոլեկցիոներ
https://www.postgresql.org/docs/current/monitoring-stats.html

Համակարգի կառավարման գործառույթներ
https://www.postgresql.org/docs/current/functions-admin.html

Ներդրեք մոդուլներ
https://www.postgresql.org/docs/current/pgstatstatements.html
https://www.postgresql.org/docs/current/pgstattuple.html
https://www.postgresql.org/docs/current/pgbuffercache.html
https://github.com/klando/pgfincore
https://github.com/dalibo/pg_stat_kcache

SQL կոմունալ ծառայություններ և sql կոդի օրինակներ
https://github.com/dataegret/pg-utils

Շնորհակալություն բոլորիդ ուշադրության համար:

Source: www.habr.com

Добавить комментарий