PostgreSQL Antipatterns. «մահացածների» ոհմակների կռիվ

PostgreSQL-ի ներքին մեխանիզմների առանձնահատկությունները թույլ են տալիս որոշ իրավիճակներում այն ​​լինել շատ արագ, իսկ մյուսներում՝ «ոչ շատ արագ»: Այսօր մենք կկենտրոնանանք հակասության դասական օրինակի վրա, թե ինչպես է աշխատում DBMS-ը և ինչ է անում մշակողը դրա հետ. UPDATE ընդդեմ MVCC սկզբունքների.

Համառոտ պատմություն ից հիանալի հոդված:

Երբ տողը փոփոխվում է UPDATE հրամանով, իրականում կատարվում է երկու գործողություն՝ DELETE և INSERT: IN տողի ընթացիկ տարբերակը xmax-ը հավասար է այն գործարքի թվին, որն իրականացրել է UPDATE-ը: Հետո այն ստեղծվում է նոր տարբերակ նույն գիծը; դրա xmin արժեքը համընկնում է նախորդ տարբերակի xmax արժեքի հետ:

Այս գործարքի ավարտից որոշ ժամանակ անց՝ հին կամ նոր տարբերակը՝ կախված COMMIT/ROOLBACK, կճանաչվի «մեռած» (մեռած tuples) անցնելիս VACUUM ըստ աղյուսակի և մաքրվել:

PostgreSQL Antipatterns. «մահացածների» ոհմակների կռիվ

Բայց դա անմիջապես տեղի չի ունենա, բայց «մահացածների» հետ կապված խնդիրները կարելի է շատ արագ ձեռք բերել՝ կրկնվող կամ գրառումների զանգվածային թարմացում մեծ սեղանի վրա, իսկ մի փոքր ուշ դուք կբախվեք նույն իրավիճակին VACUUM-ը չի կարողանա օգնել.

#1. Ես սիրում եմ այն ​​տեղափոխել

Ենթադրենք, որ ձեր բիզնեսի տրամաբանական մեթոդն ինքնին աշխատում է, և հանկարծ նա հասկանում է, որ անհրաժեշտ կլինի թարմացնել X դաշտը ինչ-որ գրառումում.

UPDATE tbl SET X = <newX> WHERE pk = $1;

Այնուհետև, երբ կատարումը զարգանում է, պարզվում է, որ Y դաշտը նույնպես պետք է թարմացվի.

UPDATE tbl SET Y = <newY> WHERE pk = $1;

... և հետո նաև Զ - ինչու՞ ժամանակ վատնել մանրուքների վրա:

UPDATE tbl SET Z = <newZ> WHERE pk = $1;

Այս գրառման քանի՞ տարբերակ ունենք հիմա տվյալների բազայում: Այո, 4 հատ: Դրանցից մեկը տեղին է, և 3-ը պետք է մաքրվեն ձեր հետևից [ավտո]վակուումով։

Մի արեք դա այսպես. Օգտագործեք թարմացնել բոլոր դաշտերը մեկ հարցումով — գրեթե միշտ մեթոդի տրամաբանությունը կարելի է փոխել այսպես.

UPDATE tbl SET X = <newX>, Y = <newY>, Z = <newZ> WHERE pk = $1;

# 2. Օգտագործումը տարբերվում է, Լյուկ:

Այսպիսով, դուք դեռ ցանկանում եք թարմացնել շատ ու շատ գրառումներ աղյուսակում (օրինակ, սցենարի կամ փոխարկիչի օգտագործման ժամանակ): Եվ նման մի բան թռչում է սցենարի մեջ.

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2;

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

UPDATE tbl SET X = <newX> WHERE pk BETWEEN $1 AND $2 AND X IS DISTINCT FROM <newX>;

Շատերը տեղյակ չեն նման հրաշալի օպերատորի գոյության մասին, ուստի ահա մի խաբեբա թերթիկ IS DISTINCT FROM և այլ տրամաբանական օպերատորներ, որոնք կօգնեն.
PostgreSQL Antipatterns. «մահացածների» ոհմակների կռիվ
... և մի փոքր համալիրի վրա գործողությունների մասին ROW()-արտահայտությունները:
PostgreSQL Antipatterns. «մահացածների» ոհմակների կռիվ

#3. Ես ճանաչում եմ իմ սիրելիին... արգելափակելով

գործարկվում են երկու նույնական զուգահեռ գործընթացներ, որոնցից յուրաքանչյուրը փորձում է նշել մուտքը, որ այն «ընթացքի մեջ է».

UPDATE tbl SET processing = TRUE WHERE pk = $1;

Նույնիսկ եթե այս գործընթացներն իրականում ինչ-որ բան անում են միմյանցից անկախ, բայց նույն ID-ի շրջանակներում, երկրորդ հաճախորդը «կողպված կլինի» այս հարցումով մինչև առաջին գործարքի ավարտը:

Լուծում թիվ 1առաջադրանքը կրճատվում է նախորդին

Պարզապես նորից ավելացնենք IS DISTINCT FROM:

UPDATE tbl SET processing = TRUE WHERE pk = $1 AND processing IS DISTINCT FROM TRUE;

Այս ձևով երկրորդ հարցումը պարզապես ոչինչ չի փոխի տվյալների բազայում, ամեն ինչ արդեն այնպես է, ինչպես պետք է լինի, հետևաբար, արգելափակում չի լինի: Այնուհետև մենք մշակում ենք կիրառական ալգորիթմում գրառումը «չգտնելու» փաստը:

Լուծում թիվ 2Խորհրդատվական կողպեքներ

Մեծ թեմա առանձին հոդվածի համար, որի մասին կարող եք կարդալ կիրառման մեթոդները և հանձնարարական արգելափակման «ռեյկը»:.

Լուծում թիվ 3: Հիմար զանգեր

Բայց սա հենց այն է, ինչ պետք է պատահի ձեզ հետ միաժամանակյա աշխատանք նույն ձայնագրությամբ? Թե՞ դուք խառնվել եք, օրինակ, հաճախորդի կողմից բիզնես տրամաբանություն կանչելու ալգորիթմներին: Իսկ եթե մտածեք դրա մասին...

Source: www.habr.com

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