PostgreSQL'de tetikleyicileri geçici olarak nasıl devre dışı bırakırım?


132

Verileri toplu olarak yüklüyorum ve tüm tetikleme değişikliklerini, satır bazında olduğundan çok daha ucuza gerçeğin ardından yeniden hesaplayabilirim.

PostgreSQL'deki tüm tetikleyicileri geçici olarak nasıl devre dışı bırakabilirim?

Yanıtlar:


164

Alternatif olarak, yalnızca KULLANICI tablosundakileri değil tüm tetikleyicileri devre dışı bırakmak istiyorsanız, şunları kullanabilirsiniz:

SET session_replication_role = replica;

Bu, mevcut oturum için tetikleyicileri devre dışı bırakır.

Aynı oturumu yeniden etkinleştirmek için:

SET session_replication_role = DEFAULT;

Kaynak: http://koo.fi/blog/2013/01/08/disable-postgresql-triggers-temporarily/


2
Muhteşem. Toplu silme işlemimi 30 dakikadan 1 saniyenin altına
düşürdü

7
Bu komutun kısıtlama tetikleyicilerini devre dışı bırakmaması da kullanışlıdır
bartolo-otrit

2
Son yarım saati, test ortamımdaki "yabancı anahtar kısıtlamalarını ihlal ediyor" hatasını atlamanın bir yolunu boşuna arayarak geçirdim ve tam olarak bu!
Amalgovinus

Bir uyarı: çalışma zamanı yapılandırma belgelerine ve ALTER TABLE belgelerine göre bu, normal tetikleyicilerle çalışır ancak ENABLE REPLICAveya ile ayarlananlarla çalışmaz ENABLE ALWAYS.
beldaz

Yayındayım 10.4ve yukarıdaki ifadeyi görmezden geliyor gibi görünüyor.
Stephane

129

PostgreSQL ALTER TABLE tblname DISABLE TRIGGER USER, ihtiyacım olanı yapıyor gibi görünen komutu biliyor . ALTER TABLE bakın .


Ve sonra "tüm tetikleme değişikliklerini nasıl yeniden hesaplarsınız"?
Wojtek Kruszewski

15
Eşzamanlı yükte dikkatli: ALTER TABLE ... DISABLE TRIGGER USERmasaya özel bir kilit gerektirir.
Erwin Brandstetter

3
@WojtekKruszewski, David'in önceden bazı bilgileri kullanarak (örneğin, tetikleyici her satırda aynı değişikliği yaparsa, bu daha verimli olabilirse) tetik tarafından yapılacak değişiklikleri manuel olarak yeniden hesaplayabileceği anlamına geldiğini düşünüyorum. tek bir UPDATE tarafından yönetilir). Bunu her durumda yapabileceğini kastettiğini sanmıyorum.
Rauni Lillemets

1
@ zyzof'un çözümü, tüm tetikleyicileri devre dışı bırakmak için daha iyidir.
uthomas

48

Devre dışı bırakma tetikleyicisi için

ALTER TABLE table_name DISABLE TRIGGER trigger_name

Tetiği etkinleştirmek için

ALTER TABLE table_name ENABLE TRIGGER trigger_name

1
Bunun için "tümünü" de kullanabilirsiniz:ALTER TABLE table_name DISABLE TRIGGER all
DenisNovac

8
SET session_replication_role = replica; 

PgAdmin'deki tablo editörü ile bir tabloyu değiştirirsem ve sıradan sorgu ile tabloyu değiştirirsem Linux makinemde PostgreSQL 9.4 ile çalışmaz. Pg_trigger tablosundaki manuel değişiklikler de sunucunun yeniden başlatılması olmadan çalışmaz, ancak postgresql.nabble.com'daki gibi dinamik sorgu VERİTABANINDAKİ TÜM TETİKLEYİCİLERİ ETKİNLEŞTİR / DEVRE DIŞI BIRAK çalışır. Ayarlamaya ihtiyaç duyduğunuzda faydalı olabilir.

Örneğin, belirli bir ad alanında tablolarınız varsa bunlar şunlar olabilir:

create or replace function disable_triggers(a boolean, nsp character varying) returns void as
$$
declare 
act character varying;
r record;
begin
    if(a is true) then
        act = 'disable';
    else
        act = 'enable';
    end if;

    for r in select c.relname from pg_namespace n
        join pg_class c on c.relnamespace = n.oid and c.relhastriggers = true
        where n.nspname = nsp
    loop
        execute format('alter table %I %s trigger all', r.relname, act); 
    end loop;
end;
$$
language plpgsql;

Tüm tetikleyicileri belirli tetikleme işleviyle devre dışı bırakmak istiyorsanız, şunlar olabilir:

create or replace function disable_trigger_func(a boolean, f character varying) returns void as
$$
declare 
act character varying;
r record;
begin
    if(a is true) then
        act = 'disable';
    else
        act = 'enable';
    end if;

    for r in select c.relname from pg_proc p 
        join pg_trigger t on t.tgfoid = p.oid
        join pg_class c on c.oid = t.tgrelid
        where p.proname = f
    loop
        execute format('alter table %I %s trigger all', r.relname, act); 
    end loop;
end;
$$
language plpgsql;

Sistem katalogları için PostgreSQL belgeleri


Tetikleme ateşleme sürecinin başka kontrol seçenekleri vardır:

ALTER TABLE ... ENABLE REPLICA TRIGGER ... - tetik yalnızca eşleme modunda çalışacaktır.

TABLO DEĞİŞTİRME ... HER ZAMAN TETİKLEMEYİ ETKİNLEŞTİR ... - tetik her zaman etkinleşir (açıkça)


7

PgAdmin (III) 'de tetikleyicileri de devre dışı bırakabilirsiniz:

  1. Masanızı bulun
  2. +
  3. Tetikleyicilerde tetikleyicinizi bulun
  4. Sağ tıklayın, "Tetikleyici Etkin mi?" Seçeneğinin işaretini kaldırın.

4
SET session_replication_role = replica;  

ayrıca Postgres 9.1'de benim için dosent işler. bazı değişikliklerle bartolo-otrit tarafından tanımlanan iki işlevi kullanıyorum. İlk işlevi benim için çalışmasını sağlamak için değiştirdim çünkü tabloyu doğru şekilde tanımlamak için ad alanı veya şema mevcut olmalıdır. Yeni kod:

CREATE OR REPLACE FUNCTION disable_triggers(a boolean, nsp character varying)
  RETURNS void AS
$BODY$
declare 
act character varying;
r record;
begin
    if(a is true) then
        act = 'disable';
    else
        act = 'enable';
    end if;

    for r in select c.relname from pg_namespace n
        join pg_class c on c.relnamespace = n.oid and c.relhastriggers = true
        where n.nspname = nsp
    loop
        execute format('alter table %I.%I %s trigger all', nsp,r.relname, act); 
    end loop;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION disable_triggers(boolean, character varying)
  OWNER TO postgres;

sonra her şema için bir seçme sorgusu yapıyorum:

SELECT disable_triggers(true,'public');
SELECT disable_triggers(true,'Adempiere');
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.