Antipatterns za PostgreSQL: badilisha data kwa kupitisha kichochezi

Hivi karibuni au baadaye, wengi wanakabiliwa na hitaji la kurekebisha kitu kwenye rekodi za jedwali. Mimi tayari niambie jinsi ya kuifanya vizuri zaidi, na jinsi gani - ni bora si kufanya hivyo. Leo nitazungumza juu ya kipengele cha pili cha sasisho la wingi - kuhusu vichochezi.

Kwa mfano, kwenye meza ambayo unahitaji kurekebisha kitu, trigger mbaya hutegemea ON UPDATE, kuhamisha mabadiliko yote kwa baadhi ya jumla. Na unahitaji kusasisha kila kitu (anzisha uga mpya, kwa mfano) kwa uangalifu sana ili hesabu hizi zisiathiriwe.

Wacha tuzima vichochezi!

BEGIN;
  ALTER TABLE ... DISABLE TRIGGER ...;
  UPDATE ...; -- Ρ‚ΡƒΡ‚ Π΄ΠΎΠ»Π³ΠΎ-Π΄ΠΎΠ»Π³ΠΎ
  ALTER TABLE ... ENABLE TRIGGER ...;
COMMIT;

Kwa kweli, hiyo ndiyo yote - kila kitu kinaning'inia.

Kwa sababu ALTER TABLE inalazimisha Ufikiaji wa Kipekee- kufuli ambayo hakuna mtu anayeendesha sambamba, hata rahisi SELECT, haitaweza kusoma chochote kutoka kwenye meza. Hiyo ni, mpaka shughuli hii itaisha, kila mtu ambaye anataka hata "kusoma" tu atasubiri. Na tunakumbuka hilo UPDATE tuna muda mrefu...

Hebu tuizime haraka, kisha tuiwashe haraka!

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

UPDATE ...;

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

Hapa hali tayari ni bora, muda wa kusubiri ni mdogo sana. Lakini shida mbili tu zinaharibu uzuri wote:

  • ALTER TABLE yenyewe inangojea shughuli zingine zote kwenye meza, pamoja na ndefu SELECT
  • Wakati kichochezi kimezimwa "kuruka na" mabadiliko yoyote mezani, hata yetu. Na haitaingia kwenye hesabu, ingawa inapaswa. Shida!

Kusimamia vigezo vya kikao

Kwa hivyo, katika toleo lililopita, tulijikwaa juu ya jambo la msingi - tunahitaji kwa njia fulani kufundisha kichochezi kutofautisha mabadiliko "yetu" kwenye jedwali kutoka "sio yetu". "Zetu" zimerukwa kama zilivyo, lakini kwa "sio zetu" zinasababishwa. Kwa hili unaweza kutumia vigezo vya kikao.

session_replication_jukumu

Soma mwongozo:

Utaratibu wa trigger pia huathiriwa na kutofautiana kwa usanidi session_replication_jukumu. Imewashwa bila maagizo ya ziada (chaguo-msingi), vichochezi vitawaka wakati jukumu la urudufishaji ni "asili" (chaguo-msingi) au "ndani". Vichochezi vimewezeshwa kwa kubainisha ENABLE REPLICA, itafanya kazi tu ikiwa hali ya kikao cha sasa - "replica", na vichochezi vimewezeshwa kwa kubainisha ENABLE ALWAYS, itafanya kazi bila kujali hali ya sasa ya urudufishaji.

Nitasisitiza hasa kwamba mpangilio hautumiki kwa wote kwa wakati mmoja, kama ALTER TABLE, lakini tu kwa muunganisho wetu maalum. Kwa jumla, ili hakuna vichochezi vya programu kufanya kazi:

SET session_replication_role = replica; -- Π²Ρ‹ΠΊΠ»ΡŽΡ‡ΠΈΠ»ΠΈ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€Ρ‹
UPDATE ...;
SET session_replication_role = DEFAULT; -- Π²Π΅Ρ€Π½ΡƒΠ»ΠΈ Π² исходноС состояниС

Hali ndani ya kichochezi

Lakini chaguo hapo juu hufanya kazi kwa vichochezi vyote mara moja (au unahitaji "kubadilisha" vichochezi mapema ambavyo hutaki kuzima). Na ikiwa tunahitaji "zima" kichochezi kimoja maalum?

Hii itatusaidia Tofauti ya kikao cha "mtumiaji".:

Majina ya vigezo vya upanuzi yameandikwa kama ifuatavyo: jina la kiendelezi likifuatiwa na nukta na kisha jina la kigezo lenyewe, sawa na majina kamili ya vitu katika SQL. Kwa mfano: plpgsql.variable_conflict.
Kwa sababu chaguo za nje ya mfumo zinaweza kuwekwa katika michakato ambayo haipakii moduli inayofaa ya kiendelezi, PostgreSQL inakubali maadili ya majina yoyote yenye vipengele viwili.

Kwanza, tunakamilisha kichochezi, kitu kama hiki:

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

Kwa njia, hii inaweza kufanyika "kwa faida", bila kuzuia, kupitia CREATE OR REPLACE kwa kazi ya trigger. Na kisha katika unganisho maalum tunacheza "yetu" kutofautisha:


SET mycfg.my_table_convert_process = 'TRUE';
UPDATE ...;
SET mycfg.my_table_convert_process = ''; -- Π²Π΅Ρ€Π½ΡƒΠ»ΠΈ Π² исходноС состояниС

Je! unajua njia zingine? Shiriki katika maoni.

Chanzo: mapenzi.com

Kuongeza maoni