ฉันจะปิดการใช้งานทริกเกอร์ชั่วคราวใน PostgreSQL ได้อย่างไร


132

ฉันกำลังโหลดข้อมูลจำนวนมากและสามารถคำนวณการปรับเปลี่ยนทริกเกอร์ทั้งหมดใหม่ได้ในราคาถูกกว่าการคำนวณแบบทีละแถว

ฉันจะปิดการใช้งานทริกเกอร์ทั้งหมดชั่วคราวใน PostgreSQL ได้อย่างไร

คำตอบ:


164

หรือหากคุณต้องการปิดทริกเกอร์ทั้งหมดไม่ใช่เฉพาะในตาราง USER คุณสามารถใช้:

SET session_replication_role = replica;

สิ่งนี้จะปิดใช้งานทริกเกอร์สำหรับเซสชันปัจจุบัน

ในการเปิดใช้งานอีกครั้งสำหรับเซสชันเดียวกัน:

SET session_replication_role = DEFAULT;

ที่มา: http://koo.fi/blog/2013/01/08/disable-postgresql-triggers-tempo Temporary/


2
น่ากลัว ทำให้การลบมวลของฉันไปจาก 30 นาทีเป็น <1 วินาที :)
Dan Lenski

7
นอกจากนี้ยังมีประโยชน์ที่คำสั่งนี้จะไม่ปิดใช้งานทริกเกอร์ข้อ จำกัด
bartolo-otrit

2
ฉันใช้เวลาครึ่งชั่วโมงที่ผ่านมาอย่างไร้ประโยชน์เพื่อหลีกเลี่ยงข้อผิดพลาด "ละเมิดข้อ จำกัด ของคีย์ต่างประเทศ" ในสภาพแวดล้อมการทดสอบของฉันและนี่คือสิ่งที่ถูกต้อง!
Amalgovinus

คำเตือน: ตามเอกสารการตั้งค่ารันไทม์และเอกสารเปลี่ยนแปลงตารางนี้จะทำงานร่วมกับทริกเกอร์ปกติ แต่ไม่ชุดที่มีหรือENABLE REPLICA ENABLE ALWAYS
beldaz

ฉันอยู่10.4และดูเหมือนว่าจะเพิกเฉยต่อข้อความข้างต้นนี้
Stephane

129

PostgreSQL รู้ALTER TABLE tblname DISABLE TRIGGER USERคำสั่งซึ่งดูเหมือนจะทำในสิ่งที่ฉันต้องการ ดูเปลี่ยนแปลงตาราง


แล้วคุณจะ "คำนวณการปรับเปลี่ยนทริกเกอร์ทั้งหมดใหม่" ได้อย่างไร?
Wojtek Kruszewski

15
ระมัดระวังในการโหลดพร้อมกัน: ALTER TABLE ... DISABLE TRIGGER USERต้องใช้ล็อคพิเศษบนโต๊ะ
Erwin Brandstetter

3
@WojtekKruszewski ฉันคิดว่า David หมายความว่าเขาสามารถคำนวณการเปลี่ยนแปลงใหม่ด้วยตนเองที่จะทำโดยทริกเกอร์โดยใช้ความรู้ก่อนหน้านี้ (เช่นหากทริกเกอร์จะทำการเปลี่ยนแปลงเหมือนกันในทุกแถวซึ่งจะมีประสิทธิภาพมากขึ้น จัดการโดย UPDATE ครั้งเดียว) ฉันไม่คิดว่าพระองค์ทรงหมายความว่าคุณสามารถทำสิ่งนี้ได้ในทุกสถานการณ์
Rauni Lillemets

1
โซลูชันของ @ zyzof ดีกว่าสำหรับการปิดใช้งานทริกเกอร์ทั้งหมด
uthomas

48

สำหรับปิดการใช้งานทริกเกอร์

ALTER TABLE table_name DISABLE TRIGGER trigger_name

สำหรับการเปิดใช้งานทริกเกอร์

ALTER TABLE table_name ENABLE TRIGGER trigger_name

1
คุณยังสามารถใช้ "ทั้งหมด" สำหรับสิ่งนี้:ALTER TABLE table_name DISABLE TRIGGER all
DenisNovac

8
SET session_replication_role = replica; 

มันใช้ไม่ได้กับ PostgreSQL 9.4 บนเครื่อง Linux ของฉันถ้าฉันเปลี่ยนตารางผ่านตัวแก้ไขตารางใน pgAdmin และใช้งานได้ถ้าฉันเปลี่ยนตารางผ่านแบบสอบถามธรรมดา การเปลี่ยนแปลงด้วยตนเองในตาราง pg_trigger จะไม่ทำงานหากไม่มีการรีสตาร์ทเซิร์ฟเวอร์ แต่แบบสอบถามแบบไดนามิกเช่นในpostgresql.nabble.com เปิดใช้งาน / ปิดใช้งานทริกเกอร์ทั้งหมดในฐานข้อมูลผลงาน อาจเป็นประโยชน์เมื่อคุณต้องการการปรับแต่ง

ตัวอย่างเช่นหากคุณมีตารางในเนมสเปซเฉพาะอาจเป็น:

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 สำหรับแค็ตตาล็อกระบบ


มีตัวเลือกการควบคุมอื่นของกระบวนการยิงทริกเกอร์:

แก้ไขตาราง ... เปิดใช้งาน REPLICA TRIGGER ... - ทริกเกอร์จะเริ่มทำงานในโหมดจำลองเท่านั้น

แก้ไขตาราง ... เปิดใช้งาน 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.