PostgreSQL Antipatterns. փոխել տվյալները՝ շրջանցելով ձգան

Վաղ թե ուշ շատերը բախվում են սեղանի գրառումներում ինչ-որ բան զանգվածաբար ուղղելու անհրաժեշտության հետ: Ես արդեն ունեմ ասաց ինձ, թե ինչպես դա անել ավելի լավ, և ինչպես - ավելի լավ է դա չանել: Այսօր ես կխոսեմ զանգվածային թարմացման երկրորդ ասպեկտի մասին. հրահրիչների մասին.

Օրինակ, սեղանի վրա, որտեղ դուք պետք է ինչ-որ բան ուղղեք, կա չար ձգան 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
  • Մինչ ձգանն անջատված է, ցանկացած փոփոխություն «կթռչի» աղյուսակում, նույնիսկ մերը չէ: Եվ այն չի մտնի ստորաբաժանումներ, թեև պետք է: Դժբախտություն։

Նստաշրջանի փոփոխականների կառավարում

Այսպիսով, նախորդ տարբերակում մենք հանդիպեցինք մի հիմնարար կետի. մենք պետք է ինչ-որ կերպ սովորեցնենք ձգանին տարբերակել աղյուսակի «մեր» փոփոխությունները «ոչ մերից»: «Մեր»-ը բաց է թողնվում այնպես, ինչպես կա, և «մերը չէ» գործարկվում է: Դրա համար կարող եք օգտագործել նստաշրջանի փոփոխականներ.

նիստի_կրկնօրինակման_դեր

Կարդացեք ձեռնարկ:

Գործարկման մեխանիզմի վրա ազդում է նաև կազմաձևման փոփոխականը նիստի_կրկնօրինակման_դեր. Երբ միացված է առանց լրացուցիչ հրահանգների (կանխադրված), գործարկիչները կաշխատեն, երբ կրկնօրինակման դերը լինի «ծագում» (կանխադրված) կամ «տեղական»: Գործարկիչները միացված են հրահանգների միջոցով 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 = ''; -- вернули в исходное состояние

Գիտե՞ք այլ ուղիներ: Կիսվեք մեկնաբանություններում։

Source: www.habr.com

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