NĂ« njĂ« moment apo tjetĂ«r, shumĂ« njerĂ«z pĂ«rballen me nevojĂ«n pĂ«r tĂ« korrigjuar masivisht tĂ« dhĂ«nat nĂ« tabela. UnĂ« tashmĂ« , si dhe pĂ«r atĂ« si â nuk Ă«shtĂ« mirĂ« tĂ« bĂ«het. Sot do tĂ« flas pĂ«r aspektin e dytĂ« tĂ« pĂ«rditĂ«simit masiv â pĂ«r funksionimin e trigger-ave.
Për shembull, në një tabelë, ku ju duhet të bëni disa ndryshime, ka një trigger të rrezikshëm ON UPDATE, i cili përcjell të gjitha ndryshimet në disa agregate. Dhe ju duhet të përditësoni gjithçka (për shembull, të inicializoni një fushë të re) në një mënyrë kaq delikate sa që këto aggregate të mos preken.
Le të mbyllim thjesht trigger-at!
BEGIN;
ALTER TABLE ... DISABLE TRIGGER ...;
UPDATE ...; -- këtu zgjat shumë
ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;NĂ« thelb, kĂ«tu Ă«shtĂ« gjithçka â gjithçka Ă«shtĂ« e aktivizuar.
Sepse ALTER TABLE vendos AccessExclusive-bllokimin, nën të cilin askush që ekzekuton paralelisht, madje as një thjesht SELECT, nuk mund të lexojë asgjë nga tabela. Pra, derisa kjo transaksion të përfundojë, të gjithë që dëshirojnë madje "thjesht të lexojnë" do të presin. Dhe ne kujtojmë se UPDATE kemi një periudhë shumë të gjatë...
Le të çaktivizojmë shpejt, pastaj ta aktivizojmë shpejt!
BEGIN;
ALTER TABLE ... DISABLE TRIGGER ...;
COMMIT;
UPDATE ...;
BEGIN;
ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;Këtu situata është më e mirë, koha e pritjes është dukshëm më e shkurtër. Por dy probleme prishin gjithë bukurinë:
ALTER TABLEai pret të gjitha operacionet e tjera në tabelë, duke përfshirë ato të gjatëSELECT- Ndërsa trigger-i është i çaktivizuar, "do të kalojë" çdo ndryshim në tabelë, madje edhe ai që nuk është tonin. Dhe në agregate nuk do të arrijë, edhe pse duhet. Një problem!
Menaxhimi i variablave të sesionit
Pra, nĂ« variantin e mĂ«parshĂ«m ne u ndeshĂ«m me njĂ« moment thelbĂ«sor â duhet tĂ« mĂ«sojmĂ« ndonjĂ«herĂ« trigger-in pĂ«r tĂ« dalluar ndryshimet "tona" nĂ« tabelĂ« nga ato "tĂ« huaja". TĂ« "tonat" le tĂ« kalojnĂ« siç janĂ«, ndĂ«rsa "tĂ« huajat" â tĂ« aktivizohen. PĂ«r kĂ«tĂ« mund tĂ« shfrytĂ«zojmĂ« .
session_replication_role
Lexojmë :
Mekanizmi i funksionimit të trigger-ave gjithashtu ndikohet nga variabla konfiguruese . Trigger-at e përfshirë pa udhëzime të tjera (për të drejtë) do të aktivizohen kur roli i replikimit është "origin" (për të drejtë) ose "local". Trigger-at e përfshirë duke e caktuar
ENABLE REPLICA, do të aktivizohen vetëm nëse modi i tanishëm i sesionit është "replica", dhe trigger-at e përfshirë duke e caktuarENABLE ALWAYS, do të aktivizohen pavarësisht nga moda e tanishme e replikimit.
Dua të theksoj veçanërisht, se kjo konfigurim nuk prek të gjitha gjithashtu, si ALTER TABLE, por një lidhje speciale të veçantë. Në total, që të mos aktivizohen ndonjëherë trigger-a aplikativë:
SET session_replication_role = replica; -- ndalova trigger-at
UPDATE ...;
SET session_replication_role = DEFAULT; -- e riktheva në gjendjen fillestareKushti brenda trigger-it
Por varianti i lartpërmendur funksionon për të gjithë trigger-at në të njëjtën kohë (ose duhet "të ndryshoni" më parë trigger-at që nuk dëshironi t'i ndaloni). Por nëse na nevojitet "të ndalojmë" një trigger konkret?
Në këtë na ndihmon :
Emrat e parametrave të zgjerimeve shkruhen në këtë mënyrë: emri i zgjerimit, pika dhe pastaj emri real i parametrit, siç janë emrat e plotë të objekteve në SQL. Për shembull: plpgsql.variable_conflict.
Të dhënat jashtë sistemit mund të vendosen në procese që nuk ngarkojnë modulin përkatës të zgjerimit, PostgreSQL pranon vlerat për çdo emër me dy komponente.
Së pari, përmirësojmë trigger-in, në këtë mënyrë:
BEGIN
-- procesi i konvertimit mund të bëjë gjithçka
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;
... PĂ«r mĂ« tepĂ«r, mund ta bĂ«jmĂ« "nĂ« kohĂ« reale", pa bllokime, pĂ«rmes KRIJO OSE ZĂVENDĂSO pĂ«r funksionin e trigger-it. NdĂ«rsa mĂ« pas nĂ« lidhjen speciale aktivizojmĂ« "variablin tonĂ«":
SET mycfg.my_table_convert_process = 'TRUE';
UPDATE ...;
SET mycfg.my_table_convert_process = ''; -- e riktheva në gjendjen fillestare
A keni njohuri për mënyra të tjera? Ndani në komentet.
Burimi: habr.com
