PostgreSQL Antipatterns: мубориза бо лашкари "мурдагон"

Хусусиятҳои механизмҳои дохилии PostgreSQL имкон медиҳанд, ки он дар баъзе ҳолатҳо хеле зуд бошад ва дар дигар ҳолатҳо «на чандон тез» бошад. Имрӯз мо ба як мисоли классикии ихтилоф байни чӣ гуна кор кардани DBMS ва он чизе ки таҳиякунанда бо он кор мекунад, тамаркуз хоҳем кард - UPDATE против принсипҳои MVCC.

Ҳикояи мухтасар аз мақолаи олӣ:

Вақте ки сатр бо фармони UPDATE тағир дода мешавад, воқеан ду амал иҷро карда мешавад: DELETE ва INSERT. ДАР версияи ҷории сатр xmax ба рақами транзаксияе, ки UPDATE анҷом дода шудааст, муқаррар карда мешавад. Он гоҳ он офарида мешавад версияи нав ҳамон хат; арзиши xmin он бо арзиши xmax версияи қаблӣ мувофиқат мекунад.

Чанде пас аз ин муомилот анҷом, версияи кӯҳна ё нав, вобаста ба COMMIT/ROOLBACK, эътироф карда мешавад "мурда" (барои мурдагон) хангоми гузаштан VACUUM мувофиқи ҷадвал ва тоза карда мешавад.

PostgreSQL Antipatterns: мубориза бо лашкари "мурдагон"

Аммо ин дарҳол рӯй нахоҳад дод, аммо мушкилотро бо "мурдагон" хеле зуд ба даст овардан мумкин аст - бо такрор ё такрор навсозии оммавии сабтҳо дар як мизи калон, ва каме дертар шумо хоҳад ҳамон вазъият дучор ВАКУМ кумак карда наметавонад.

# 1: Ман мехоҳам онро кӯчонам

Фарз мекунем, ки усули шумо дар мантиқи тиҷорӣ кор мекунад ва ногаҳон он дарк мекунад, ки барои навсозии майдони X дар ягон сабт зарур аст:

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

Пас, ҳангоми пешрафти иҷро, маълум мешавад, ки майдони Y низ бояд нав карда шавад:

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

... ва он гоҳ инчунин Z - чаро вақтро ба чизҳои ночиз сарф мекунанд?

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: зангҳои беақл

Аммо ин маҳз ҳамон чизест, ки бояд бо шумо рӯй диҳад кори ҳамзамон бо як сабт? Ё шумо, масалан, бо алгоритмҳои занги мантиқи тиҷорӣ дар тарафи муштарӣ халалдор кардаед? Ва агар шумо дар ин бора фикр кунед?..

Манбаъ: will.com

Илова Эзоҳ