PostgreSQL-teenpatrone: verander data deur 'n sneller te omseil

Vroeër of later word baie gekonfronteer met die behoefte om iets in die tabelrekords massaal reg te maak. Ek het reeds vertel my hoe om dit beter te doen, en hoe - dit is beter om dit nie te doen nie. Vandag sal ek praat oor die tweede aspek van die massa-opdatering - oor snellers.

Byvoorbeeld, op 'n tafel waarin jy iets moet regmaak, hang 'n bose sneller ON UPDATE, wat alle veranderinge na sommige aggregate oordra. En jy moet alles opdateer (byvoorbeeld 'n nuwe veld initialiseer) so versigtig dat hierdie aggregate nie geraak word nie.

Kom ons deaktiveer net die snellers!

BEGIN;
  ALTER TABLE ... DISABLE TRIGGER ...;
  UPDATE ...; -- тут долго-долго
  ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;

Eintlik, dit is al - alles hang.

omdat ALTER TABLE oplê Toegang eksklusief- 'n slot waaronder niemand parallel hardloop nie, selfs 'n eenvoudige een SELECT, sal niks uit die tabel kan lees nie. Dit wil sê, totdat hierdie transaksie eindig, sal almal wat selfs wil "net lees" wag. En ons onthou dit UPDATE ons het 'n lang...

Kom ons skakel dit vinnig af, skakel dit dan vinnig aan!

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

UPDATE ...;

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

Hier is die situasie reeds beter, die wagtyd is baie minder. Maar net twee probleme bederf al die skoonheid:

  • ALTER TABLE self wag vir alle ander operasies op die tafel, insluitende langes SELECT
  • Terwyl die sneller af is "vlieg verby" enige verandering in die tabel, nie eers ons s'n nie. En dit sal nie in die aggregate kom nie, hoewel dit moet. Moeilikheid!

Bestuur van sessieveranderlikes

Dus, in die vorige weergawe het ons op 'n fundamentele punt afgekom - ons moet op een of ander manier die sneller leer om "ons" veranderinge in die tabel van "nie ons s'n" te onderskei nie. "Ons s'n" word oorgeslaan soos dit is, maar op "nie ons s'n nie" word dit geaktiveer. Hiervoor kan jy gebruik sessie veranderlikes.

sessie_replikasie_rol

lees handleiding:

Die snellermeganisme word ook deur die konfigurasieveranderlike beïnvloed sessie_replikasie_rol. Geaktiveer sonder bykomende instruksies (verstek), sal snellers begin wanneer die replikasierol "oorsprong" (verstek) of "plaaslik" is. Snellers geaktiveer deur te spesifiseer ENABLE REPLICA, sal slegs werk as huidige sessiemodus - "replika", en snellers geaktiveer deur te spesifiseer ENABLE ALWAYS, sal werk ongeag die huidige replikasiemodus.

Ek sal veral beklemtoon dat die instelling nie op alles tegelyk van toepassing is nie, soos ALTER TABLE, maar slegs na ons aparte spesiale verbintenis. In totaal, sodat geen toepassingsnellers werk nie:

SET session_replication_role = replica; -- выключили триггеры
UPDATE ...;
SET session_replication_role = DEFAULT; -- вернули в исходное состояние

Toestand binne sneller

Maar die bogenoemde opsie werk vir alle snellers gelyktydig (of jy moet vooraf snellers "verwissel" wat jy nie wil deaktiveer nie). En as ons nodig het "skakel af" een spesifieke sneller?

Dit sal ons help "gebruiker" sessie veranderlike:

Uitbreidingsparametername word soos volg geskryf: die uitbreidingsnaam gevolg deur 'n punt en dan die parameternaam self, soortgelyk aan volle voorwerpname in SQL. Byvoorbeeld: plpgsql.variable_conflict.
Omdat buite-stelsel opsies ingestel kan word in prosesse wat nie die toepaslike uitbreidingsmodule laai nie, aanvaar PostgreSQL waardes vir enige name met twee komponente.

Eerstens finaliseer ons die sneller, iets soos hierdie:

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

Terloops, dit kan "vir wins" gedoen word, sonder om te blokkeer, deur CREATE OR REPLACE vir die snellerfunksie. En dan in die spesiale verband gebruik ons ​​"ons" veranderlike:


SET mycfg.my_table_convert_process = 'TRUE';
UPDATE ...;
SET mycfg.my_table_convert_process = ''; -- вернули в исходное состояние

Ken jy ander maniere? Deel in die kommentaar.

Bron: will.com

Voeg 'n opmerking