PostgreSQL Antipatterns: өдөөгчийг алгасаж өгөгдлийг өөрчлөх

Эрт орой хэзээ нэгэн цагт олон хүн хүснэгтийн бүртгэлд ямар нэг зүйлийг их хэмжээгээр засах шаардлагатай тулгардаг. Би аль хэдийн байна яаж илүү сайн хийхийг надад хэлээч, мөн хэрхэн - үүнийг хийхгүй байх нь дээр. Өнөөдөр би олон нийтийн шинэчлэлийн хоёр дахь асуудлын талаар ярих болно - өдөөгчүүдийн тухай.

Жишээлбэл, ямар нэг зүйлийг засах шаардлагатай ширээн дээр муу гох өлгөгдсөн байдаг ON UPDATE, бүх өөрчлөлтийг зарим нэгдэл рүү шилжүүлэх. Мөн та эдгээр агрегатуудад нөлөөлөхгүйн тулд бүх зүйлийг (жишээ нь шинэ талбарыг эхлүүлэх) маш болгоомжтой шинэчлэх хэрэгтэй.

Зүгээр л өдөөгчийг идэвхгүй болгоё!

BEGIN;
  ALTER TABLE ... DISABLE TRIGGER ...;
  UPDATE ...; -- тут долго-долго
  ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;

Үнэндээ, энэ бүгд - бүх зүйл өлгөөтэй байна.

Яагаад гэвэл ALTER TABLE ногдуулдаг Онцгой хандалт- энгийн ч гэсэн хэн ч зэрэгцэн ажилладаггүй түгжээ SELECT, хүснэгтээс юу ч унших боломжгүй болно. Өөрөөр хэлбэл, энэ гүйлгээ дуусах хүртэл "уншихыг" хүссэн хүн бүр хүлээх болно. Тэгээд бид үүнийг санаж байна UPDATE Бидэнд удаан хугацаа байна ...

Үүнийг хурдан унтраа, дараа нь хурдан асаацгаая!

BEGIN;
  ALTER TABLE ... DISABLE TRIGGER ...;
COMMIT;

UPDATE ...;

BEGIN;
  ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;

Энд байдал аль хэдийн сайжирч, хүлээх хугацаа хамаагүй бага байна. Гэхдээ зөвхөн хоёр асуудал бүх гоо сайхныг сүйтгэдэг:

  • ALTER TABLE өөрөө ширээн дээрх бусад бүх үйлдлүүд, түүний дотор урт үйлдлүүдийг хүлээж байдаг SELECT
  • Гох унтраалттай байхад аливаа өөрчлөлтийг "нисэх" Хүснэгтэнд, тэр байтугай манайх ч биш. Энэ нь шаардлагатай хэдий ч нэгдэлд орохгүй. Асуудал!

Сеанс хувьсагчдыг удирдах

Тиймээс, өмнөх хувилбарт бид нэг үндсэн цэг дээр бүдэрсэн - бид ямар нэгэн байдлаар хүснэгтийн "бидний" өөрчлөлтийг "биднийх биш" -ээс ялгахын тулд гохыг заах хэрэгтэй. "Манайх"-ыг байгаагаар нь алгасаж, харин "биднийх биш"-ийг идэвхжүүлдэг. Үүний тулд та ашиглаж болно сесс хувьсагчид.

сессийн_хуулбарлах_үрэг

Уншсан гарын авлага:

Гох механизмд тохиргооны хувьсагч мөн нөлөөлдөг сессийн_хуулбарлах_үрэг. Нэмэлт зааваргүйгээр идэвхжүүлсэн (өгөгдмөл), хуулбарлах үүрэг нь "эх" (анхдагч) эсвэл "орон нутгийн" байх үед триггерүүд ажиллах болно. Өдөөгчийг зааж өгснөөр идэвхжүүлсэн ENABLE REPLICA, зөвхөн тохиолдолд л ажиллана одоогийн сесс горим - "хуулбар", мөн триггерийг зааж өгснөөр идэвхжүүлсэн ENABLE ALWAYS, одоогийн хуулбарлах горимоос үл хамааран ажиллах болно.

Энэ тохиргоо нь бүгдэд нэг дор хамаарахгүй гэдгийг би онцлон тэмдэглэх болно ALTER TABLE, гэхдээ зөвхөн бидний тусдаа тусгай холболт. Нийтдээ ямар ч програм ажиллахгүй байхын тулд:

SET session_replication_role = replica; -- выключили триггеры
UPDATE ...;
SET session_replication_role = DEFAULT; -- вернули в исходное состояние

Триггер доторх нөхцөл байдал

Гэхдээ дээрх сонголт нь бүх триггерүүдэд нэгэн зэрэг ажиллана (эсвэл та идэвхгүй болгохыг хүсэхгүй байгаа триггерүүдийг урьдчилан "солих" хэрэгтэй). Мөн бидэнд хэрэгтэй бол тодорхой нэг гохыг "унтраах"?

Энэ нь бидэнд туслах болно "хэрэглэгч" сесс хувьсагч:

Өргөтгөлийн параметрийн нэрийг дараах байдлаар бичнэ: өргөтгөлийн нэр, дараа нь цэг, дараа нь параметрийн нэр нь SQL дээрх объектын бүтэн нэртэй төстэй. Жишээ нь: plpgsql.variable_conflict.
Тохиромжтой өргөтгөлийн модулийг ачаалдаггүй процессуудад системээс гадуурх сонголтуудыг тохируулж болох тул PostgreSQL хоёр бүрэлдэхүүн хэсэгтэй аливаа нэрсийн утгууд.

Эхлээд бид гохыг эцэслэнэ, үүнтэй төстэй зүйл:

BEGIN
    -- процессу конвертации можно делать все
    IF current_setting('mycfg.my_table_convert_process') = 'TRUE' THEN
        IF TG_OP IN ('INSERT', 'UPDATE') THEN
            RETURN NEW;
        ELSE
            RETURN OLD;
        END IF;
    END IF;
...

Дашрамд хэлэхэд, үүнийг "ашгийн төлөө" хийж болно, хаалтгүйгээр, дамжуулан CREATE OR REPLACE гох функцийн хувьд. Тэгээд дараа нь тусгай холболтоор бид "өөрийн" хувьсагчийг холбодог:


SET mycfg.my_table_convert_process = 'TRUE';
UPDATE ...;
SET mycfg.my_table_convert_process = ''; -- вернули в исходное состояние

Та өөр аргуудыг мэдэх үү? Сэтгэгдэл дээр хуваалцаарай.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх