PostgreSQL에서 트리거를 일시적으로 비활성화하려면 어떻게합니까?


131

나는 데이터를 대량으로로드하고 있으며 사실보다 훨씬 저렴하게 모든 트리거 수정을 다시 계산할 수 있습니다.

PostgreSQL에서 모든 트리거를 일시적으로 비활성화하려면 어떻게해야합니까?

답변:


163

또는 USER 테이블의 트리거뿐만 아니라 모든 트리거를 비활성화하려는 경우 다음을 사용할 수 있습니다.

SET session_replication_role = replica;

현재 세션에 대한 트리거를 비활성화합니다.

동일한 세션에서 다시 활성화하려면

SET session_replication_role = DEFAULT;

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


2
대박. 대량 삭제를 30 분에서 <1 초로 만들었습니다.)
Dan Lenski

7
이 명령은하지 비활성화 제약 트리거를 수행하는 것도 편리합니다
BARTOLO - otrit

2
내 테스트 환경에서 "외래 키 제약 조건 위반"오류를 우회하는 방법을 찾기 위해 지난 30 분을 헛되이 보냈습니다.
Amalgovinus

한 가지주의 사항 : 런타임 구성 문서ALTER TABLE 문서에 따르면 일반 트리거에서는 작동하지만 ENABLE REPLICA또는로 설정된 트리거에서는 작동하지 않습니다 ENABLE ALWAYS.
beldaz

나는 위에 10.4있으며 위의 진술을 무시하는 것 같습니다.
Stephane

129

PostgreSQL은 ALTER TABLE tblname DISABLE TRIGGER USER명령을 알고 있으며 , 필요한 작업을 수행하는 것 같습니다. ALTER TABLE을 참조하십시오 .


그리고 어떻게 "모든 트리거 수정을 다시 계산"합니까?
Wojtek Kruszewski

15
동시로드에주의 : ALTER TABLE ... DISABLE TRIGGER USER테이블에 대한 독점 잠금이 필요합니다.
Erwin Brandstetter

3
@WojtekKruszewski, David는 사전 지식을 사용하여 트리거로 수행 한 변경 사항을 수동으로 다시 계산할 수 있음을 의미한다고 생각합니다 (예 : 트리거가 모든 행에서 동일한 변경을 수행하면 더 효율적일 수 있음) 단일 업데이트로 처리). 나는 그가 당신이 모든 상황에서 이것을 할 수 있다는 것을 의미하지 않았다고 생각합니다.
Rauni Lillemets

1
@zyzof의 솔루션은 모든 트리거를 비활성화하는 것이 좋습니다.
uthomas

48

비활성화 트리거

ALTER TABLE table_name DISABLE TRIGGER trigger_name

활성화 트리거

ALTER TABLE table_name ENABLE TRIGGER trigger_name

1
이를 위해 "all"을 사용할 수도 있습니다.ALTER TABLE table_name DISABLE TRIGGER all
DenisNovac

8
SET session_replication_role = replica; 

pgAdmin에서 테이블 편집기를 통해 테이블을 변경하면 Linux 컴퓨터에서 PostgreSQL 9.4와 작동하지 않으며 일반 쿼리를 통해 테이블을 변경하면 작동합니다. pg_trigger 테이블의 수동 변경도 서버를 다시 시작하지 않아도 작동하지만 postgresql.nabble.com 과 같은 동적 쿼리는 데이터베이스의 ENABLE / DISABLE ALL TRIGGERS 작동합니다. 튜닝이 필요할 때 유용 할 수 있습니다.

예를 들어 특정 네임 스페이스에 테이블이 있으면 다음과 같습니다.

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;

특정 트리거 기능으로 모든 트리거를 비활성화하려면 다음을 수행하십시오.

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;

시스템 카탈로그에 대한 PostgreSQL 설명서


트리거 발생 프로세스에는 다른 제어 옵션이 있습니다.

ALTER TABLE ... ENABLE REPLICA TRIGGER ...-트리거는 복제 모드에서만 실행됩니다.

ALTER TABLE ... 항상 TRIGGER 활성화 ...-트리거는 항상 (분명히) 발생합니다


7

pgAdmin (III)에서 트리거를 비활성화 할 수도 있습니다.

  1. 테이블 찾기
  2. +를 확장하십시오
  3. 트리거에서 트리거 찾기
  4. 마우스 오른쪽 버튼을 클릭하고 "Trigger Enabled?"를 선택 취소하십시오.

4
SET session_replication_role = replica;  

Postgres 9.1에서도 저를 위해 일했습니다. 나는 약간의 수정으로 bartolo-otrit에 의해 설명 된 두 가지 기능을 사용합니다. 네임 스페이스 또는 스키마가 있어야 테이블을 올바르게 식별 할 수 있기 때문에 첫 번째 함수가 작동하도록 수정했습니다. 새로운 코드는 다음과 같습니다.

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;

그런 다음 모든 스키마에 대해 선택 쿼리를 수행합니다.

SELECT disable_triggers(true,'public');
SELECT disable_triggers(true,'Adempiere');
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.