PostgreSQL Antipatterns: "өлгөндөрдүн" аскерлери менен күрөшүү

PostgreSQLдин ички механизмдеринин өзгөчөлүктөрү анын кээ бир кырдаалдарда өтө тез, ал эми башкаларында "өтө ылдам эмес" болушуна мүмкүндүк берет. Бүгүн биз DBMS кантип иштээри менен иштеп чыгуучунун аны менен кылган ишинин ортосундагы чыр-чатактын классикалык мисалына токтолобуз - UPDATE vs MVCC принциптери.

Кыскача окуядан сонун макала:

Качан катар UPDATE буйругу менен өзгөртүлгөндө, чындыгында эки операция аткарылат: DELETE жана INSERT. IN саптын учурдагы версиясы 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 даана! Алардын бири тиешелүү, ал эми үчөөнү сизден кийин [auto]VACUUM аркылуу тазалашыңыз керек.

Мындай кылба! Колдонуу бир суроодо бардык талааларды жаңыртуу — дээрлик ар дайым методдун логикасын төмөнкүдөй өзгөртүүгө болот:

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

Комментарий кошуу