PĂ«r njĂ« moment tĂ« caktuar, shumĂ« ndodhen pĂ«rballĂ« nevojĂ«s pĂ«r tĂ« bĂ«rĂ« disa korrigjime masive nĂ« regjistrimet e tabelĂ«s. UnĂ« tashmĂ« , si dhe pĂ«r atĂ« se si nuk duhet ta bĂ«ni. Sot do tĂ« flas pĂ«r aspektin e dytĂ« tĂ« pĂ«rditĂ«simit masiv â pĂ«r aktivizimin e triggereve.
Për shembull, në tabelën ku duhet të bëni disa ndryshime, ka një trigger të padëshirueshëm ON UPDATE, që transferon të gjitha ndryshimet në disa agregate. Dhe ju duhet të përditësoni gjithçka (të inicializoni një fushë të re, për shembull) në një mënyrë kaq të kujdesshme sa që ato agregate të mos preken.
Le t'i fikim thjesht triggere!
BEGIN;
ALTER TABLE ... DISABLE TRIGGER ...;
UPDATE ...; -- këtu do të zgjaste
ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;Kjo Ă«shtĂ« e gjitha â gjithçka tashmĂ« Ă«shtĂ« nĂ« suspens.
Sepse ALTER TABLE ngarkon bllokimin AccessExclusive-bllokimi, nën të cilin askush që po ekzekuton paralelisht, madje edhe një i thjeshtë SELECT, nuk do të jetë i aftë të lexojë asgjë nga tabela. Do të thotë se derisa kjo transaksion të përfundojë, të gjithë ata që duan madje "thjesht të lexojnë" do të presin. Dhe ne e mbajmë mend se UPDATE kemi një shumë-lloog ...
Le t'i fikim shpejt, pastaj t'i kthejmë shpejt!
BEGIN;
ALTER TABLE ... DISABLE TRIGGER ...;
COMMIT;
UPDATE ...;
BEGIN;
ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;Tani situata është më e mirë, koha e pritjes është dukshëm më e shkurtër. Por dy probleme prishet gjithë bukurinë:
ALTER TABLEvetë pret të gjitha operacionet e tjera në tabelë, duke përfshirë ato të gjataSELECT- Ndërsa triggeri është i fikur, "do të kalojë" çdo ndryshim në tabelë, madje edhe ato që nuk janë tonat. Dhe atyre agregate me siguri nuk do t'u shkojnë, edhe pse duhet. Katastrofë!
Menaxhimi i variablave të sesionit
Pra, nĂ« versionin e mĂ«parshĂ«m ne u pĂ«rballĂ«m me njĂ« moment themelor â duhet tĂ« mĂ«sojmĂ« triggerin tĂ« dallojĂ« ndryshimet "tona" nĂ« tabelĂ« nga "tĂ« huajat". TĂ« "tonat" tĂ« kalojnĂ« ashtu si janĂ«, ndĂ«rsa ato "tĂ« huaja" â tĂ« aktivizohen. PĂ«r kĂ«tĂ«, mund tĂ« pĂ«rdorim .
session_replication_role
Lexojmë :
Mekanizmi i aktivizimit të triggereve gjithashtu ndikohet nga variabla konfiguruese . Triggerët e aktivizuar pa udhëzime të tjera (në mënyrë të paracaktuar) do të aktivizohen kur roli i replikimit është "origin" (në parazgjedhje) ose "local". Triggerët të aktivizuar duke specifikuar
ENABLE REPLICA, do tĂ« aktivizohen vetĂ«m nĂ«se reĆŸimi aktual i sesionit Ă«shtĂ« "replica", dhe triggerĂ«t tĂ« aktivizuar duke specifikuarENABLE ALWAYS, do tĂ« aktivizohen pavarĂ«sisht nga aktuali regjimi i replikimit.
Dua të theksoj se kjo konfigurim i takon jo të gjithëve, si ALTER TABLE, dhe jo në lidhje me lidhjen tonë të veçantë. Në përfundim, për të mos aktivizuar ndonjë mënyrë njoftimi:
SET session_replication_role = replica; -- çaktivizoi njoftimet
UPDATE ...;
SET session_replication_role = DEFAULT; -- ktheu në gjendjen fillestareKushti brenda njoftimit
Por, opsioni i mësipërm funksionon për të gjitha njoftimet njëherazi (apo duhet të "ndryshojmë" paraprakisht njoftimet që nuk duam të çaktivizojmë). Po nëse na nevojitet "çaktivizimi" i një njoftimi të caktuar?
Në këtë na ndihmon :
Emrat e parametrave të zgjerimeve shkruhen në këtë mënyrë: emri i zgjerimit, pika dhe pastaj emri i parametrave, si emrat e plota të objekteve në SQL. Për shembull: plpgsql.variable_conflict.
Të gjitha parametrat jashtë sistemit mund të vendosen në procese që nuk ngarkojnë modulin e zgjerimit përkatës, PostgreSQL pranon vlera për çdo emër me dy komponente.
Së pari, përmirësojmë njoftimin, përafërsisht kështu:
BEGIN
-- në procesin e konvertimit mund të bëjmë 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, kjo mund të bëhet "në qershi", pa bllokime, përmes CREATE OR REPLACE për funksionin e njoftimit. Pastaj në lidhjen speciale vendosim "variablën" tonë:
SET mycfg.my_table_convert_process = 'TRUE';
UPDATE ...;
SET mycfg.my_table_convert_process = ''; -- ktheu në gjendjen fillestare
Dini mënyra të tjera? Ndani në komentet.
Burimi: habr.com
