PostgreSQL Antipatterns: daneyan bi guheztinek biguhezînin

Zû an dereng, gelek kes bi hewcedariya ku bi girseyî tiştek di tomarên tabloyê de rast bikin re rû bi rû ne. Min berê xwe da ji min re got ku meriv wê çawa çêtir bike, û çawa - çêtir e ku meriv wiya neke. Îro ez ê li ser beşa duyemîn a nûvekirina girseyî biaxivim - li ser tetikan.

Mînakî, li ser tabloyek ku hûn hewce ne ku tiştek rast bikin, tetikek xirab heye ON UPDATE, veguheztina hemî guhertinan li hin koman. Û hûn hewce ne ku her tiştî nûve bikin (mînakek qadek nû dest pê bikin) bi baldarî ku ev berhevok neyên bandor kirin.

Ka em tenê tetikan vemirînin!

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

Bi rastî, ew hemî - her tişt jixwe daliqandî ye.

Ber ku ALTER TABLE ferz dike Access Exclusive- kilîteke ku di binê wê de kes bi paralelî naherike, hetta yekî sade SELECT, dê nikaribin tiştekî ji sifrê bixwînin. Ango, heya ku ev danûstendin biqede, her kesê ku bixwaze "tenê bixwîne" dê li bendê bimîne. Û em vê yekê bi bîr tînin UPDATE demeke dirêj me heye...

Werin em zû vemirînin, paşê zû vekin!

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

UPDATE ...;

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

Li vir rewş jixwe baştir e, dema bendê pir kêm e. Lê tenê du pirsgirêk hemî bedewiyê xera dikin:

  • ALTER TABLE xwe li benda hemû operasyonên din ên li ser sifrê, di nav de yên dirêj SELECT
  • Dema ku tetikê vemire, her guhertin dê "bifire" di sifrê de, ne ya me jî. Û ew ê nekeve nav yekîneyan, her çend divê. Astengan!

Birêvebirina Guherbarên Rûniştinê

Ji ber vê yekê, di guhertoya berê de em rastî xalek bingehîn hatin - pêdivî ye ku em bi rengekî fêrî tetikê bikin ku guheztinên "me" yên di tabloyê de ji "ne yên me" cuda bikin. "Ya me" wekî ku heye tê paşguh kirin, û "ne ya me" tê kişandin. Ji bo vê yekê hûn dikarin bikar bînin guherbarên danişînê.

session_replication_role

Em dixwînin destî:

Mekanîzmaya tetikê jî ji hêla guhêrbar veavakirinê ve tê bandor kirin session_replication_role. Dema ku bêyî rêwerzên din were aktîfkirin (default), gava ku rola dubarekirinê "esîl" (pêşbirk) an "herêmî" be, tîrêj dê bişewitin. Çêker ji hêla talîmatan ve têne çalak kirin ENABLE REPLICA, dê tenê bixebite eger moda rûniştina heyî - "Replica", û tetikan bi destnîşankirinê çalak kirin ENABLE ALWAYS, bêyî ku moda nûvekirinê ya heyî bête dest pê kirin.

Ez dixwazim bi taybetî tekez bikim ku verastkirin bi yekcarî ji her kesî re derbas nabe, wekî ALTER TABLE, lê tenê ji bo girêdana meya taybetî ya cuda. Bi tevahî, ji bo ku tu pêlên serîlêdanê neyên avêtin:

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

Rewşa hundurê tetikê

Lê vebijarka jorîn ji bo hemî teşqeleyan bi yekcarî dixebite (an jî hûn hewce ne ku di pêş de pêlên ku hûn naxwazin neçalak bikin "biguhezînin"). Û eger em hewce ne "vemirîne" yek tetikek taybetî?

Ev dê alîkariya me bike guherbara danişîna "bikarhêner".:

Navên parametreyên dirêjkirinê bi vî rengî têne nivîsandin: navê dirêjkirinê, xal, û dûv re jî navê parametreyê bixwe, mîna navên bi tevahî jêhatî yên di SQL de. Mînak: plpgsql.variable_conflict.
Ji ber ku vebijarkên ne-pergalê dikarin di pêvajoyên ku modula dirêjkirina têkildar bar nakin de werin danîn, PostgreSQL qebûl dike nirx ji bo her navên bi du beşan.

Pêşî em tetikê diguherînin, tiştek mîna vê:

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

Bi awayê, ev dikare "zindî", bêyî astengkirin, bi rê ve were kirin CREATE OR REPLACE ji bo fonksiyona tetikê. Û dûv re di pêwendiya taybetî de me guhêrbar "me" saz kir:


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

Hûn bi awayên din dizanin? Di şîroveyan de parve bikin.

Source: www.habr.com