Mga Antipattern sa PostgreSQL: usba ang datos sa pag-bypass sa usa ka gatilyo

Sa madugay o sa madali, daghan ang nag-atubang sa panginahanglan sa pag-ayo sa usa ka butang sa mga talaan sa lamesa. naa na ko sultihi ko unsaon pagbuhat niini nga mas maayo, ug unsaon - mas maayo nga dili kini buhaton. Karon maghisgot ako bahin sa ikaduhang aspeto sa mass update - mahitungod sa mga trigger.

Pananglitan, sa usa ka lamesa diin kinahanglan nimo nga ayohon ang usa ka butang, usa ka daotan nga gatilyo nagbitay ON UPDATE, pagbalhin sa tanang kausaban ngadto sa pipila ka mga aggregate. Ug kinahanglan nimo nga i-update ang tanan (pagsugod sa usa ka bag-ong natad, pananglitan) pag-ayo nga kini nga mga aggregate dili maapektuhan.

Atong i-disable ang mga gatilyo!

BEGIN;
  ALTER TABLE ... DISABLE TRIGGER ...;
  UPDATE ...; -- Ρ‚ΡƒΡ‚ Π΄ΠΎΠ»Π³ΠΎ-Π΄ΠΎΠ»Π³ΠΎ
  ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;

Sa tinuud, mao ra kana - ang tanan nagbitay.

Tungod ALTER TABLE nagpahamtang Pag-access sa Eksklusibo- usa ka kandado nga wala’y usa nga nagdagan nga managsama, bisan usa ka yano SELECT, dili makabasa bisan unsa gikan sa lamesa. Sa ato pa, hangtod mahuman kini nga transaksyon, ang tanan nga gusto bisan "magbasa lang" maghulat. Ug atong mahinumduman kana UPDATE dugay mi...

Palongon ta dayon, dayon i-on dayon!

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

UPDATE ...;

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

Dinhi ang kahimtang mas maayo, ang oras sa paghulat labi ka gamay. Apan duha ra nga mga problema ang makadaot sa tanan nga katahum:

  • ALTER TABLE sa iyang kaugalingon naghulat alang sa tanan nga uban nga mga operasyon sa lamesa, lakip na ang mga taas SELECT
  • Samtang gipalong ang gatilyo, "molupad pinaagi sa" bisan unsang pagbag-o sa lamesa, dili bisan sa ato. Ug dili kini makuha sa mga aggregate, bisan kung kinahanglan. Kasamok!

Pagdumala sa mga variable sa sesyon

Mao nga, sa miaging bersyon, nakit-an namon ang usa ka sukaranan nga punto - kinahanglan naton itudlo ang gatilyo aron mailhan ang "atong" mga pagbag-o sa lamesa gikan sa "dili amon". Ang "amo" gilaktawan nga ingon, apan sa "dili sa atoa" sila na-trigger. Alang niini mahimo nimong gamiton mga variable sa sesyon.

session_replication_role

Basaha manwal:

Ang mekanismo sa pag-trigger naapektuhan usab sa variable sa pag-configure session_replication_role. Gi-enable nga walay dugang nga mga instruksyon (default), ang mga trigger modilaab kung ang papel sa pagkopya kay "gigikanan" (default) o "lokal". Gipalihok ang mga trigger pinaagi sa pagpiho ENABLE REPLICA, motrabaho lang kon kasamtangan nga mode sa sesyon - "replica", ug ang mga trigger gipagana pinaagi sa pagpiho ENABLE ALWAYS, molihok bisan unsa pa ang karon nga mode sa pagkopya.

Ilabi na nga akong hatagan og gibug-aton nga ang setting dili magamit sa tanan-tanan sa usa ka higayon, ingon ALTER TABLE, apan sa among bulag nga espesyal nga koneksyon. Sa kinatibuk-an, aron walay aplikasyon nga makapalihok sa pagtrabaho:

SET session_replication_role = replica; -- Π²Ρ‹ΠΊΠ»ΡŽΡ‡ΠΈΠ»ΠΈ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹
UPDATE ...;
SET session_replication_role = DEFAULT; -- Π²Π΅Ρ€Π½ΡƒΠ»ΠΈ Π² исходноС состояниС

Kondisyon sa sulod trigger

Apan ang kapilian sa ibabaw magamit alang sa tanan nga mga nag-trigger sa usa ka higayon (o kinahanglan nimo nga "mag-alternate" nga mga trigger nga abante nga dili nimo gusto nga ma-disable). Ug kung kinahanglan naton "i-off" ang usa ka piho nga trigger?

Makatabang kini kanato "user" nga sesyon nga variable:

Ang mga ngalan sa parameter sa extension gisulat sama sa mosunod: ang ngalan sa extension nga gisundan sa usa ka tulbok ug dayon ang ngalan sa parameter mismo, susama sa tibuok nga ngalan sa butang sa SQL. Pananglitan: plpgsql.variable_conflict.
Tungod kay ang out-of-system nga mga opsyon mahimong itakda sa mga proseso nga wala magkarga sa angay nga extension module, gidawat sa PostgreSQL mga kantidad alang sa bisan unsang mga ngalan nga adunay duha ka sangkap.

Una, atong tapuson ang gatilyo, sama niini:

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;
...

Pinaagi sa dalan, kini mahimo nga "alang sa ganansya", nga walay pagbabag, pinaagi sa CREATE OR REPLACE alang sa trigger function. Ug unya sa espesyal nga koneksyon among gi-cock ang "among" variable:


SET mycfg.my_table_convert_process = 'TRUE';
UPDATE ...;
SET mycfg.my_table_convert_process = ''; -- Π²Π΅Ρ€Π½ΡƒΠ»ΠΈ Π² исходноС состояниС

Nahibal-an ba nimo ang ubang mga paagi? Ipakigbahin sa mga komento.

Source: www.habr.com

Idugang sa usa ka comment