Làm cách nào để tạm thời vô hiệu hóa trình kích hoạt trong PostgreSQL?


131

Tôi đang tải dữ liệu hàng loạt và có thể tính lại tất cả các sửa đổi kích hoạt với giá rẻ hơn nhiều so với thực tế so với trên cơ sở từng hàng.

Làm cách nào tôi có thể tạm thời vô hiệu hóa tất cả các kích hoạt trong PostgreSQL?

Câu trả lời:


162

Ngoài ra, nếu bạn muốn tắt tất cả các kích hoạt, không chỉ các kích hoạt trên bảng USER, bạn có thể sử dụng:

SET session_replication_role = replica;

Điều này vô hiệu hóa kích hoạt cho phiên hiện tại.

Để kích hoạt lại cho cùng một phiên:

SET session_replication_role = DEFAULT;

Nguồn: http://koo.fi/blog/2013/01/08/disable-postgresql-triggers-temporantly/


2
Tuyệt vời. Làm cho việc xóa hàng loạt của tôi chuyển từ 30 phút xuống <1 giây :)
Dan Lenski

7
Cũng rất hữu ích khi lệnh này không vô hiệu hóa các kích hoạt ràng buộc
bartolo-otrit

2
Tôi đã dành nửa giờ cuối cùng để tìm kiếm một cách vô ích để vượt qua lỗi "vi phạm các ràng buộc khóa ngoại" trong môi trường thử nghiệm của mình và đây chính xác là điều đó!
Amalgovinus

Một cảnh báo: theo các tài liệu cấu hình thời gian chạy và các tài liệu ALTER TABLE, điều này sẽ hoạt động với các kích hoạt thông thường nhưng không phải là các thiết lập có ENABLE REPLICAhoặc ENABLE ALWAYS.
beldaz

Tôi đang trên 10.4và dường như bỏ qua tuyên bố trên.
Stephane

129

PostgreSQL biết ALTER TABLE tblname DISABLE TRIGGER USERlệnh, dường như làm những gì tôi cần. Xem BẢNG TUYỆT VỜI .


Và sau đó, làm thế nào để bạn "tính lại tất cả các sửa đổi kích hoạt"?
Wojtek Kruszewski

15
Cẩn thận với tải đồng thời: ALTER TABLE ... DISABLE TRIGGER USERyêu cầu một khóa độc quyền trên bàn.
Erwin Brandstetter

3
@WojtekKruszewski, tôi nghĩ rằng David có nghĩa là anh ta có thể tính toán lại các thay đổi theo cách thủ công đã thực hiện bằng cách kích hoạt, bằng cách sử dụng một số kiến ​​thức trước đó (ví dụ: nếu trình kích hoạt sẽ tạo ra thay đổi tương tự ở mỗi hàng, có thể hiệu quả hơn xử lý bởi một CẬP NHẬT duy nhất). Tôi không nghĩ rằng Ngài có nghĩa là Bạn có thể làm điều này trong mọi tình huống.
Rauni Lillemets

1
Giải pháp của @ zyzof là tốt hơn để vô hiệu hóa tất cả các kích hoạt.
uthomas

48

Để vô hiệu hóa kích hoạt

ALTER TABLE table_name DISABLE TRIGGER trigger_name

Để kích hoạt kích hoạt

ALTER TABLE table_name ENABLE TRIGGER trigger_name

1
Bạn cũng có thể sử dụng "tất cả" cho việc này:ALTER TABLE table_name DISABLE TRIGGER all
DenisNovac

8
SET session_replication_role = replica; 

Nó không hoạt động với PostgreQuery 9.4 trên máy Linux của tôi nếu tôi thay đổi bảng thông qua trình soạn thảo bảng trong pgAdmin và hoạt động nếu tôi thay đổi bảng thông qua truy vấn thông thường. Các thay đổi thủ công trong bảng pg_trigger cũng không hoạt động nếu không khởi động lại máy chủ mà truy vấn động như trên postgresql.nabble.com ENABLE / DISABLE ALL TRIGGERS IN DATABASE hoạt động. Nó có thể hữu ích khi bạn cần một số điều chỉnh.

Ví dụ: nếu bạn có các bảng trong một không gian tên cụ thể thì đó có thể là:

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;

Nếu bạn muốn tắt tất cả các kích hoạt với chức năng kích hoạt nhất định, đó có thể là:

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;

Tài liệu PostgreSQL cho danh mục hệ thống


Có một tùy chọn điều khiển khác của quá trình bắn kích hoạt:

ALTER TABLE ... ENABLE REPLICA TRIGGER ... - kích hoạt sẽ chỉ kích hoạt ở chế độ bản sao.

ALTER TABLE ... ENABLE LUÔN LUÔN TRIGGER ... - kích hoạt sẽ luôn luôn kích hoạt (rõ ràng)


7

Bạn cũng có thể tắt các kích hoạt trong pgAdmin (III):

  1. Tìm bàn của bạn
  2. Mở rộng +
  3. Tìm kích hoạt của bạn trong Triggers
  4. Nhấp chuột phải, bỏ chọn "Kích hoạt kích hoạt?"

4
SET session_replication_role = replica;  

cũng là công việc hiệu quả đối với tôi trong Postgres 9.1. tôi sử dụng hai chức năng được mô tả bởi bartolo-otrit với một số sửa đổi. Tôi đã sửa đổi hàm đầu tiên để làm cho nó hoạt động với tôi vì không gian tên hoặc lược đồ phải có mặt để xác định bảng chính xác. Mã mới là:

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;

sau đó tôi chỉ cần thực hiện một truy vấn chọn cho mọi lược đồ:

SELECT disable_triggers(true,'public');
SELECT disable_triggers(true,'Adempiere');
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.