PostgreSQL Antipatterns: ngarobah data ngaliwatan pemicu

Sooner atanapi engké, loba anu Nyanghareupan kabutuhan massively ngalereskeun hal dina rékaman méja. Kuring geus ngabejaan ka kuring kumaha ngalakukeun eta hadé, jeung kumaha - eta leuwih hade teu ngalakukeun eta. Dinten ieu kuring bakal ngobrol ngeunaan aspék kadua update massa - ngeunaan micu.

Salaku conto, dina méja dimana anjeun kedah ngalereskeun hiji hal, pemicu jahat ngagantung ON UPDATE, mindahkeun sadaya parobahan ka sababaraha agrégat. Jeung anjeun kudu ngamutahirkeun sagalana (initialize widang anyar, contona) sangkan taliti yén aggregates ieu teu kapangaruhan.

Hayu urang ngan mareuman pemicu!

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

Sabenerna, éta sadayana - sagalana ngagantung.

Kusabab ALTER TABLE maksakeun Aksés Eksklusif- konci anu teu aya anu ngajalankeun paralel, bahkan anu saderhana SELECT, moal bisa maca nanaon tina tabél. Nyaéta, dugi ka transaksi ieu réngsé, sadayana anu hoyong "ngan ukur maca" bakal ngantosan. Sareng urang émut éta UPDATE urang panjang...

Hayu urang gancang pareumkeun, teras gancang hurungkeun!

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

UPDATE ...;

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

Di dieu kaayaan geus hadé, waktu nungguan leuwih saeutik. Tapi ngan ukur dua masalah anu ngarusak kaéndahan:

  • ALTER TABLE sorangan ngantosan sagala operasi sejenna dina tabél, kaasup panjang SELECT
  • Bari pemicuna pareum "ngapung ku" robah sagala dina tabél, malah teu urang. Sarta eta moal meunang kana aggregates, sanajan sakuduna. Kasulitan!

Ngatur variabel sési

Janten, dina versi sateuacana, urang mendakan titik dasar - urang kedah kumaha waé ngajarkeun pemicu pikeun ngabédakeun parobahan "urang" dina tabél tina "henteu milik urang". "Our" anu skipped sakumaha anu kasebut, tapi dina "henteu milik urang" aranjeunna dipicu. Pikeun ieu anjeun tiasa nganggo variabel sési.

session_replication_role

Maca manual:

Mékanisme pemicu ogé kapangaruhan ku variabel konfigurasi session_replication_role. Diaktipkeun tanpa parentah tambahan (standar), pemicu bakal seuneu lamun peran réplikasi "asal" (standar) atawa "lokal". Pemicu diaktipkeun ku nangtukeun ENABLE REPLICA, bakal dianggo ngan lamun mode sési ayeuna - "replika", sarta pemicu diaktipkeun ku nangtukeun ENABLE ALWAYS, bakal dianggo paduli mode réplikasi ayeuna.

Kuring utamana bakal ngantebkeun yén setelan teu dilarapkeun ka sadaya-sadayana sakaligus, siga ALTER TABLE, tapi ngan pikeun sambungan husus urang misah. Dina total, supados henteu aya aplikasi anu memicu damel:

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

Kaayaan di jero pemicu

Tapi pilihan di luhur lumaku pikeun sakabéh micu sakaligus (atawa anjeun kudu "silih" micu sateuacanna nu teu hayang nganonaktipkeun). Sareng upami urang peryogi "Pareuman" hiji pemicu husus?

Ieu bakal nulungan urang variabel sési "pamaké".:

Ngaran parameter ekstensi ditulis kieu: ngaran extension dituturkeun ku titik lajeng nami parameter sorangan, sarupa jeung ngaran objék lengkep dina SQL. Contona: plpgsql.variable_conflict.
Kusabab pilihan kaluar-sistem bisa diatur dina prosés nu teu muka modul extension luyu, PostgreSQL narima nilai pikeun sagala ngaran jeung dua komponén.

Kahiji, urang finalize pemicu, hal kawas kieu:

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

Ku jalan kitu, ieu bisa dipigawé "kanggo kauntungan", tanpa blocking, ngaliwatan CREATE OR REPLACE pikeun fungsi pemicu. Lajeng dina sambungan husus urang cock "kami" variabel:


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

Naha anjeun terang cara anu sanés? Bagikeun dina komentar.

sumber: www.habr.com

Tambahkeun komentar