2014-07-14 7 views
5

में एक लचीला ढंग से एक ट्रिगर छोड़ कैसे मैं इसे अब जरूरत है, क्योंकि उत्पादन ट्रिगर में एक वर्तमान में ड्रॉप करने के लिए देख रहा हूँ, लेकिन समस्या यह है कि जब मैं सबसे आसान तरीका है, जोPostgreSQL

की तरह कुछ है कोशिश
drop trigger <triggername> on <tablename> 

यह एक विशाल टेबल लॉक का कारण बन गया और सब कुछ जम गया!

क्या ट्रिगर करता है:

जब एक पंक्ति सम्मिलित या अद्यतन किया जाता है, एक क्षेत्र की सामग्री को जाँच के लिए इसे विभाजित और एक अन्य तालिका पॉप्युलेट।

मुझे अपने उत्पादन वातावरण में परेशानी के बिना तत्काल अक्षम (और बाद में छोड़ना) कैसे आगे बढ़ना चाहिए?

अग्रिम और मेरे अंग्रेजी के लिए खेद धन्यवाद;)

उत्तर

7

आप ALTER TABLE ... DISABLE TRIGGER की कोशिश कर सकते हैं - लेकिन यह ताला की एक ही शक्ति की आवश्यकता है, तो मुझे नहीं लगता कि यह आप बहुत अच्छा काम करेंगे।

ALTER TABLE बनाने के लिए PostgreSQL 9.4 में कुछ काम करने के लिए कमजोर ताले लेते हैं। यह इसके साथ मदद कर सकता है।

इसी समय, मैं ट्रिगर को एक साधारण नो-ऑप फ़ंक्शन के साथ बदलने के लिए CREATE OR REPLACE FUNCTION था।

फिर, वास्तव में ट्रिगर ड्रॉप करने, मैं शायद एक स्क्रिप्ट है कि करता है लिखते हैं:

BEGIN; 
LOCK TABLE the_table IN ACCESS EXCLUSIVE MODE NOWAIT; 
DROP TRIGGER ...; 
COMMIT; 

किसी तालिका स्क्रिप्ट LOCK TABLE पर रद्द कर देगा का उपयोग कर रहा है।

मैं इसे सफल होने तक इसे एक लूप में चलाऊंगा।

यदि वह काम नहीं किया था, लेकिन अगर सबसे लेनदेन वास्तव में कम थे, मैं बिना एक LOCK TABLENOWAIT प्रयास कर सकते हैं, लेकिन एक छोटी statement_timeout सेट (यदि तालिका हमेशा व्यस्त है)। तो लिपि कुछ ऐसा होगा:

BEGIN; 
SET LOCAL statement_timeout = '5s'; 
LOCK TABLE the_table IN ACCESS EXCLUSIVE MODE NOWAIT; 
DROP TRIGGER ...; 
COMMIT; 

यह समय पर नौकरी को पूरा नहीं कर सकता है, तो विफल होने से काफी कम व्यवधान सुनिश्चित करता है। दोबारा, जब तक यह सफल नहीं हुआ तब तक मैं इसे समय-समय पर चलाऊंगा।

यदि न तो दृष्टिकोण प्रभावी था - कहें, लंबे समय से चलने वाले लेनदेन के कारण - मैं शायद इसे थोड़ी देर के लिए लॉक करने की आवश्यकता को स्वीकार करूंगा। मैं drop trigger शुरू करूंगा, तो मैं pg_terminate_backend सभी समवर्ती लेन-देन करता हूं जो टेबल पर ताले लगाते हैं ताकि उनके कनेक्शन गिर जाए और उनके लेनदेन समाप्त हो जाएं। इससे drop trigger अधिक व्यवधान की लागत पर तत्काल आगे बढ़ने देगा। यदि आप अपने ऐप्स अच्छी तरह से लिखे गए हैं तो आप केवल इस तरह के दृष्टिकोण पर विचार कर सकते हैं ताकि वे कनेक्शन बूंदों जैसे क्षणिक त्रुटियों पर लेन-देन का पुनः प्रयास कर सकें।

एक और संभावित तरीका सिस्टम कैटलॉग को सीधे संशोधित करके ट्रिगर को अक्षम (ड्रॉप नहीं) करना है।

+3

मुझे लगता है कि आपके दूसरे SQL कथन में 'NOWAIT' एक गलती है। –

+0

अच्छा, पूरा जवाब के लिए बहुत बहुत धन्यवाद! मैं जल्द ही यह कोशिश करूंगा लेकिन प्रदान की गई जानकारी बहुत अच्छी थी और मुझे जो चाहिए उसे पूरा करने के तरीके शामिल हैं! बहुत बढ़िया! – Krynble

+0

बस एक नोट जोड़कर, मैंने क्वेरी चलाई और यह एक आकर्षण की तरह काम किया! तत्काल ड्रॉप ट्रिगर पूरी तरह लचीला!आपका बहुत बहुत धन्यवाद! – Krynble