PostgreSQL Antipatterns: ngganti data liwat pemicu

Cepet utawa mengko, akeh sing ngadhepi karo perlu kanggo massively ndandani soko ing cathetan meja. Aku wis pitutur marang aku carane nindakake iku luwih apik, lan carane - iku luwih apik kanggo ora nindakaken. Dina iki aku bakal ngomong babagan aspek kapindho nganyari massa - babagan pemicu.

Contone, ing meja sing sampeyan kudu ndandani, pemicu ala macet ON UPDATE, nransfer kabeh owah-owahan menyang sawetara agregat. Lan sampeyan kudu nganyari kabeh (miwiti lapangan anyar, contone) kanthi ati-ati supaya agregat kasebut ora kena pengaruh.

Ayo mateni pemicu!

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

Sejatine, iku kabeh - kabeh gantung.

Amarga ALTER TABLE nemtokke Akses Eksklusif- kunci sing ora ana sing mlaku sejajar, malah sing prasaja SELECT, ora bakal bisa maca apa-apa saka meja. Sing, nganti transaksi iki rampung, saben wong sing pengin malah "mung maca" bakal ngenteni. Lan kita elinga UPDATE kita wis dawa ...

Ayo cepet dipateni, banjur cepet urip!

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

UPDATE ...;

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

Ing kene kahanan wis luwih apik, wektu nunggu luwih sithik. Nanging mung rong masalah ngrusak kabeh kaendahan:

  • ALTER TABLE dhewe ngenteni kabeh operasi liyane ing meja, kalebu dawa SELECT
  • Nalika pemicu mati "mabur kanthi" owah-owahan apa wae ing meja, ora malah kita. Lan ora bakal entuk agregat, sanajan kudu. alangan!

Ngatur variabel sesi

Dadi, ing versi sadurunge, kita kesandhung ing titik dhasar - kita kudu piye wae ngajari pemicu kanggo mbedakake owah-owahan "kita" ing tabel saka "ora kita". "Kita" dilewati, nanging "dudu kita" dipicu. Kanggo iki sampeyan bisa nggunakake variabel sesi.

session_replication_role

Wacan manual:

Mekanisme pemicu uga kena pengaruh variabel konfigurasi session_replication_role. Diaktifake tanpa instruksi tambahan (standar), pemicu bakal murub nalika peran replikasi "asal" (standar) utawa "lokal". Pemicu diaktifake kanthi nemtokake ENABLE REPLICA, bakal bisa mung yen mode sesi saiki - "replika", lan pemicu diaktifake kanthi nemtokake ENABLE ALWAYS, bakal bisa digunakake preduli saka mode replikasi saiki.

Aku utamanΓ© bakal nandheske sing setelan ora aplikasi kanggo kabeh-kabeh bebarengan, minangka ALTER TABLE, nanging mung kanggo sambungan khusus kita kapisah. Secara total, supaya ora ana aplikasi sing bisa nyebabake:

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

Kondisi ing njero pemicu

Nanging pilihan ing ndhuwur bisa digunakake kanggo kabeh pemicu bebarengan (utawa sampeyan kudu "sulih" pemicu ing advance sing sampeyan ora pengin mateni). Lan yen kita perlu "pateni" siji pemicu tartamtu?

Iki bakal mbantu kita variabel sesi "pangguna".:

Jeneng paramèter ekstensi ditulis kaya ing ngisor iki: jeneng ekstensi diikuti titik banjur jeneng parameter kasebut, padha karo jeneng obyek lengkap ing SQL. Contone: plpgsql.variable_conflict.
Amarga opsi metu saka sistem bisa disetel ing proses sing ora ngemot modul ekstensi sing cocog, PostgreSQL nampa Nilai kanggo jeneng apa wae kanthi rong komponen.

Kaping pisanan, kita ngrampungake pemicu, kaya iki:

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

Miturut cara, iki bisa ditindakake "kanggo bathi", tanpa ngalangi, liwat CREATE OR REPLACE kanggo fungsi pemicu. Banjur ing sambungan khusus kita jago variabel "kita":


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

Apa sampeyan ngerti cara liya? Nuduhake ing komentar.

Source: www.habr.com

Add a comment