Ավելի վաղ թե ուշ շատերը բախվում են անհրաժեշտությանը մաքսայինորեն ինչ-որ բան շտկել աղյուսակի գրառումներում։ Ես արդեն , իսկ ինչպես՝ ավելի լավ չէ։ Ա TODAY ես պատմում եմ երկրորդ ասպեկտի մասին ` տրիգերների գործում.
Օրինակ, այն աղյուսակում, որտեղ դուք պետք է ինչ-որ բան շտկեք, կախված է չար թրի ON UPDATE, որը տեղափոխում է բոլոր փոփոխությունները ինչ-որ ագրեգատների։ Իսկ ձեզ հարկավոր է բոլորովին վերաբերել (новое поле проинициализировать, օրինակ) այնքան զգուշորեն, որ այդ ագրեգատները չկտրվեն։
Եկեք պարզապես անջատենք թիրաբարները!
BEGIN;
ALTER TABLE ... DISABLE TRIGGER ...;
UPDATE ...; -- здесь долго-долго
ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;Բանն այն է, որ այստեղ էլ ամեն ինչ՝ բոլորը արդեն կախված է.
Որովհետև ALTER TABLE ներգրավել է AccessExclusive-արգելափակումը, որի տակ ոչ մեկը զուգընթաց իրականացնող, նույնիսկ պարզ SELECT, ոչինչ աղյուսակից կարդալ չի կարող։ Այժմ այս գործառնությունը չի ավարտվի, բոլոր ցանկացողները նույնիսկ «միայն կարդալ» սպասելու են։ Եվ մենք հիշում ենք, որ UPDATE մեր մոտ բացատրող է…
Եկեք այնպես արագ անջատենք, հետո արագ կավելացնենք!
BEGIN;
ALTER TABLE ... DISABLE TRIGGER ...;
COMMIT;
UPDATE ...;
BEGIN;
ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;Այստեղ իրավիճակը արդեն լավ է, սպասման ժամանակը զգալիորեն նվազում է։ Բայց երկու խնդիրները վատացնում են ողջ գեղեցկությունը․
ALTER TABLEնա սպասում է բոլոր մյուս գործողություններին աղյուսակի վրա, ներառյալ երկարSELECT- Մինչդեռ թրիգերը անջատված է, «անցնում է որևէ փոփոխություն» աղյուսակում, նույնիսկ մեր։ Եվ ագրեգատներ, ինչ-որ կերպ չի մտնի, ինչ-որ կերպ պետք է։ Վշտություն!
Ն SESSION փոփոխականների կառավարում
Այդ իսկ պատճառով, նախորդ տարբերակում մենք հանդիպեցինք հիմնարար կետին՝ պետք է ինչ-որ ձևով ուսուցնենք թրիգերին տարբերակել «մեր» փոփոխությունները աղյուսակում «չմեր»։ «Մեր» թողնել այնպես, ինչպես կա, իսկ «չմեր»՝ գործողության ժամանակ։ Bunun için可以 воспользоваться .
session_replication_role
Կարդում ենք :
Թրի գոտու աշխատման մեխանիզմին նաև ազդում է կոնֆիգուրացիոն փոփոխականը։ Հավաստվածները, որ առանց լրացուցիչ ցուցումների (առանձնապես), թրիգերները աշխատում են, երբ կրկնության դերակատարությունը՝ «origin» (առանձնապես) կամ «local»։ Թրիգերները, որոնք ակտիվանում են ENABLE REPLICA
, կաշխատեն միայն եթենշանակված տվյալ դիրքերը — «replica», իսկ թրիգերները, որոնք ակտիվանում են ENABLE ALWAYS, կաշխատեն անկախ տվյալ կրկնության իրավիճակներից։Հատուկ ընդգծում եմ, որ կարգավորումը վերաբերում է ոչ բոլորին, ինչպես
, այլ միայն մեր առանձնահատուկ մասնագիտությանը։ Այժմ, որպեսզի ոչ մի իրական կիրառական կամ մեխանիկա չաշխատեն որպես՝ ALTER TABLESET 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;
... Մեծ օրինակի շնորհիվ, դա կարելի է անել «սկսած», առանց բլոկավորման, միջոցով ՍՏԵՊՈՒ ԶՎԻՏԻՆ Առաջին առանցքային ֆունկցիայի համար։ Իսկ հետո հատուկ կապի միջոցով ակտիվացնում ենք «մեր» փոփոխականը՝
SET mycfg.my_table_convert_process = 'TRUE';
UPDATE ...;
SET mycfg.my_table_convert_process = ''; -- վերադարձել էլեկտրական վիճակին
Գիտե՞ք այլ եղանակներ։ կիսվեք մեկնաբանություններում։
Ընտանիք: habr.com
