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