Varsti vĂ”i hiljem puutuvad paljud kokku vajadusega midagi massiliselt tabeli kirjetes parandada. Olen juba , ja kuidas â mitte teha. TĂ€na rÀÀgin massiivse uuendamise teisest aspektist â kĂ€ivituvatest trigeritest.
NÀiteks, tabelil, kus peate midagi korrigeerima, on kurja triger ON UPDATE, mis viib kÔik muudatused mingitesse aggregeeridesse. Ja teil on vaja kÔik uuendada (uue vÀlja initsialiseerida nÀiteks) nii ettevaatlikult, et need aggregeedid ei puudutaks.
LĂ€hme lihtsalt trigerite vĂ€ljalĂŒlitamise teed!
BEGIN;
ALTER TABLE ... DISABLE TRIGGER ...;
UPDATE ...; -- siin lÀheb kaua
ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;Loomulikult, siin see kĂ”ik on â kĂ”ik on juba kĂ€imas.
Sest ALTER TABLE kehtestab AccessExclusive-lukustuse all, mille all keegi, kes teostab samaaegset tööd, isegi lihtne SELECT, ei saa tabelist midagi lugeda. See tĂ€hendab, et kuni see tehing ei ole lĂ”ppenud, ootavad kĂ”ik, kes tahavad isegi 'lihtsalt lugeda'. Ja me mĂ€letame, et KUUDA meil on pi-ii-ikaltâŠ
LĂ€hme siis kiiresti vĂ€lja lĂŒlitama, siis kiiresti sisse lĂŒlitame!
BEGIN;
ALTER TABLE ... DISABLE TRIGGER ...;
COMMIT;
UPDATE ...;
BEGIN;
ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;Siin on olukord juba parem, ooteaeg on oluliselt lĂŒhem. Kuid kaks probleemi rikuvad kogu ilu:
ALTER TABLEootab endiselt kĂ”iki teisi operatsioone tabelis, sealhulgas pikkiSELECT- Praegu on triger vĂ€lja lĂŒlitatud, igal muutusel on vĂ”imalus «mööda minna» tabelis, isegi mitte meie oma. Ja agregaatidesse ei pÀÀse, kuigi peaks. HĂ€da!
Seansi muutujate haldamine
Nii et eelmisel variandil sattusime pĂ”himĂ”ttelisele punktile â peame kuidagi Ă”petama triggest eristama tabelis «meie» muudatusi «mitte meie» omadest. «Meie» lubame sellisena, kuid «mitte meie» korral peame reageerima. Selleks saab kasutada .
session_replication_role
Lugeda :
Triggerite aktiveerimise mehhanismile mĂ”jutab ka konfiguratsioonimuutuja . Ilma tĂ€iendavate mĂ€rkusteta (vaikimisi) aktiveeruvad triggerrid, kui replikatsiooni roll on â âoriginâ (vaikimisi) vĂ”i âlocalâ. Trigged, mis aktiveeritakse nĂ€idatud
ENABLE REPLICA, aktiveeruvad ainult siis, kui praegune seanss on â âreplicaâ, ning trigged, mis aktiveeritakse nĂ€idatudENABLE ALWAYS, aktiveeruvad olenemata praegusest replikatsiooni reĆŸiimist.
Eriti rĂ”hutan, et seadistus ei kehti kĂ”igile korraga, nagu ALTER TABLE, vaid ainult meie konkreetse spetsiaalsete ĂŒhenduste jaoks. Seega, et ei toimiks mingeid rakenduslikke kĂ€ivitusmehhanisme:
SET session_replication_role = replica; -- keelame kÀivitushoobad
UPDATE ...;
SET session_replication_role = DEFAULT; -- taastame algse seisundiKĂ€ivitushoobade tingimus
Kuid eespool toodud variant töötab kĂ”igi kĂ€ivitushoobade jaoks korraga (vĂ”i peab eelnevalt "muutma" neid kĂ€ivitushoobasid, mida ei soovi keelata). Aga kui me peame "keelama" ĂŒhe konkreetse kĂ€ivitushoova?
Seda aitab meil :
Laiendite parameetrite nimed kirjutatakse jÀrgmiselt: laiendi nimi, punkt ja seejÀrel parameetri enda nimi, sarnaselt SQL-i tÀielike objektinimedega. NÀiteks: plpgsql.variable_conflict.
Kuna sĂŒsteemi vĂ€list parameetrit vĂ”ib seadistada protsessides, mis ei laadita vastavat laiendimoodulit, aktsepteerib PostgreSQL vÀÀrtusi igasuguste kahe komponendiga nimede jaoks.
Alustame kÀivitushoova tÀiustamist umbes nii:
BEGIN
-- konverteerimisprotsessis vÔib teha kÔike
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;
... Ăksikasjalikult, seda saab teha "reaalses" ajas, ilma blokeeringuteta, lĂ€bi CREATE OR REPLACE triggereid funktsioonide jaoks. SeejĂ€rel mÀÀrame spetsiaalses ĂŒhenduses meie muutuja:
SET mycfg.my_table_convert_process = 'TRUE';
UPDATE ...;
SET mycfg.my_table_convert_process = ''; -- taastatud algsesse olekusse
Kas tead muid viise? Jagage kommentaarides.
Allikas: habr.com
