लाइव प्रोडक्शन डेटाबेस पर ऑल्टर टेबल


24

कैसे सबसे "लोकप्रिय" (MySQL, Postgres ...) डेटाबेस सिस्टम लाइव उत्पादन डेटाबेस (जैसे जोड़ने, हटाने या कोलम के प्रकार को बदलने) पर तालिकाओं को बदलने का काम करता है?

मुझे पता है कि सही तरीका यह है कि सब कुछ शेड्यूल डाउनटाइम पर बैकअप करें और फिर बदलाव करें।

लेकिन ... क्या कोई भी मौजूदा डेटाबेस सिस्टम इन चीजों को "ऑन-लाइन" बिना किसी चीज को रोकने का समर्थन करता है? (शायद उन प्रश्नों में देरी करना जो एक स्तंभ को संदर्भित करते हैं जो अभी बदला जा रहा है / हटा दिया गया है)

और क्या होता है जब मैं सिर्फ ALTER TABLE...एक जीवित डेटाबेस पर करता हूं ? क्या ऐसा होने पर सब कुछ रुक जाता है? क्या डेटा दूषित हो सकता है? आदि।

फिर से, मैं ज्यादातर पोस्टग्रेज या MySQL का जिक्र कर रहा हूं क्योंकि ये वही हैं जिनका मैं सामना करता हूं।

(और, हाँ, कभी भी मुझे ऐसा करने से पहले मुझे यह करना पड़ा "यह सही तरीका है", चीजों को बैक अप करना, डाउनटाइन को शेड्यूल करना आदि ... लेकिन मैं यह जानना चाहता हूं कि क्या यह संभव है और इस तरह से "त्वरित"। गंदा "या यदि कोई DB प्रणाली है जो वास्तव में" त्वरित, लाइव और गंदे "स्कीमा परिवर्तन के लिए समर्थन करती है)


किसी ने सुझाव दिया फेसबुक स्क्रिप्ट से MySQL के लिए ऑनलाइन स्कीमा बदलें (एक ट्यूटोरियल के साथ यहाँ और स्रोत यहाँ ) ... एक अच्छा तरीका "hacky" यह करने के लिए तरीके का एक सेट स्वचालित करने के लिए की तरह लगता है ... क्या कभी किसी ने यह प्रयोग किया जाता है कुछ उत्पादन जैसा दिखता है?


3
नोट: "सही तरीका" विशिष्ट MySQL के सापेक्ष है और PostgreSQL के लिए नहीं। PostgreSQL में "सही तरीका" आमतौर पर बहुत आसान है, हालांकि इसमें शामिल हो सकता है। pg_reorgअधिक कठिन परिदृश्यों के साथ मदद का उपयोग ।
शॉन

मुझे इस पर एक विस्तृत वीडियो पसंद आया होगा, जिसमें कोई व्यक्ति अधिक से अधिक रणनीतियों को समझा सकेगा।
संदीपन नाथ

जवाबों:


22

जब आप ALTER TABLEPostgreSQL में एक इश्यू करते हैं तो यह एक ACCESS EXCLUSIVEलॉक लेगा जिसमें सब कुछ शामिल हैSELECT । हालाँकि, यह लॉक काफी संक्षिप्त हो सकता है यदि तालिका को फिर से लिखने की आवश्यकता नहीं है, तो कोई नया UNIQUE, CHECKया FOREIGN KEYबाधाओं को सत्यापित करने के लिए महंगे पूर्ण-टेबल स्कैन की आवश्यकता नहीं है, आदि।

यदि संदेह है, तो आप आम तौर पर इसे आज़मा सकते हैं! PostgreSQL में सभी DDL ट्रांजेक्शनल है, इसलिए ALTER TABLEयदि इसे बहुत लंबा लगता है और अन्य प्रश्नों को पकड़ना शुरू करना रद्द करना काफी ठीक है । विभिन्न कमांड द्वारा आवश्यक लॉक स्तर को लॉकिंग पेज में प्रलेखित किया जाता है

कुछ सामान्य-धीमे संचालन को बिना डाउनटाइम के प्रदर्शन करने के लिए सुरक्षित किया जा सकता है। उदाहरण के लिए, यदि आप तालिका है tऔर आप स्तंभ में परिवर्तन करना चाहते customercode integer NOT NULLकरने के लिए textक्योंकि ग्राहक सभी ग्राहक कोड अब एक साथ शुरू होगा फैसला किया है X, तो आप लिख सकते हैं:

ALTER TABLE t ALTER COLUMN customercode TYPE text USING ( 'X'||customercode::text );

... लेकिन वह फिर से लिखने के लिए पूरी मेज पर ताला लगा देगा। तो एक के साथ एक कॉलम जोड़ रहा है DEFAULT। यह लंबे लॉक से बचने के लिए कुछ चरणों में किया जा सकता है, लेकिन अनुप्रयोगों को अस्थायी दोहराव से निपटने में सक्षम होना चाहिए:

ALTER TABLE t ADD COLUMN customercode_new text;
BEGIN;
LOCK TABLE t IN EXCLUSIVE MODE;
UPDATE t SET customercode_new = 'X'||customercode::text;
ALTER TABLE t DROP COLUMN customercode;
ALTER TABLE t RENAME COLUMN customercode_new TO customercode;
COMMIT;

यह केवल प्रक्रिया के दौरान लिखने से रोकेगा t; ताला नाम EXCLUSIVEकुछ इस तरह से भ्रामक है कि इसमें सभी चीजों को छोड़करSELECT ; ACCESS EXCLUSIVEमोड केवल एक ही है कि शामिल नहीं बिल्कुल everyting है। लॉक मोड देखें । एक जोखिम है कि लॉक द्वारा अपग्रेड किए जाने के कारण यह ऑपरेशन गतिरोध-रोलबैक हो सकता है ALTER TABLE, लेकिन कम से कम आपको बस इसे फिर से करना होगा।

तुम भी है कि ताला से बचने और पूरी बात पर एक ट्रिगर समारोह बनाने के द्वारा लाइव कर सकते हैं tकि जब भी एक INSERTया UPDATEमें, स्वचालित रूप से भरता आता है customercode_newसे customercode

वहाँ भी तरह अंतर्निहित हैं उपकरण CREATE INDEX CONCURRENTLYऔर ALTER TABLE ... ADD table_constraint_using_indexthat're DBAs संगामिति के अनुकूल तरीके से और धीरे धीरे काम कर रही द्वारा विशेष लॉकिंग अवधि कम करने के लिए अनुमति देने के लिए बनाया गया है।

pg_reorgउपकरण या उसके उत्तराधिकारी pg_repackके रूप में अच्छी तरह से कुछ तालिका के पुनर्गठन के संचालन के लिए इस्तेमाल किया जा सकता।


1
@Craig ने जो कहा उसमें प्रमुख बात यह थी, "अगर इसे दोबारा लिखने की आवश्यकता नहीं है।" एक ALTER TABLE t ADD COLUMN i INTबार लॉक हासिल करने के बाद एक तेज़ ऑपरेशन (आमतौर पर <1ms) का उपयोग करना । लॉक हासिल करने पर, कनेक्शन को कतारबद्ध किया जा सकता है, हालांकि, यह "फ्री" नहीं है ... हालांकि यह दुनिया का बेहतर है जो आपको MySQL में करना है। एक NOT NULLबाधा जोड़ना अधिक कठिन है और दिल की बीमारी के लिए नहीं।
शॉन

यह सर्वसम्मति से प्रतीत होता है कि pg_repackकिसका बेहतर उत्तराधिकारी है pg_reorg
इरविन ब्रान्डेसटेटर

अच्छा जवाब, डिफ़ॉल्ट (या गणना) के साथ एक स्तंभ जोड़ने के बारे में एक कम "अवरुद्ध" तरीका है एक पूरी नई तालिका बनाना, सम्मिलित करने / अद्यतन / हटाने के लिए पुरानी तालिका को अवरुद्ध करें लेकिन चयन का चयन करें और नए को आबाद करें। अंत में चयन के लिए पुरानी तालिका पर एक संक्षिप्त अनन्य लॉक जारी करें, इसे हटा दें और पुराने के लिए नया नाम बदलें। अपने परिदृश्य के आधार पर आप पुराने में आवेषण को अवरुद्ध किए बिना नए को आबाद करना भी शुरू कर सकते हैं और उस विशेष हल को जारी करते हुए विशेष लॉक लगा सकते हैं (उम्मीद है कि सिर्फ कुछ नए रिकॉर्ड सम्मिलित कर रहे हैं)
jean

7

Percona ऑनलाइन स्कीमा परिवर्तन करने के लिए अपने स्वयं के उपकरण के साथ आया है

टूल को pt-online-schema-change कहा जाता है

इसमें ट्रिगर शामिल हैं, इसलिए कृपया ध्यान से प्रलेखन पढ़ें।

प्रलेखन के अनुसार, किए गए प्रमुख ऑपरेशन हैं

  • स्वच्छता की जाँच
  • ठस
  • ऑनलाइन स्कीमा परिवर्तन
    • अस्थायी तालिका बनाएं और बदलें
    • तालिका से अस्थायी तालिका में परिवर्तन कैप्चर करें
    • तालिका से अस्थायी तालिका तक पंक्तियों की प्रतिलिपि बनाएँ
    • तालिका और अस्थायी तालिका को सिंक्रनाइज़ करें
    • स्वैप और तालिका का नाम बदलें और अस्थायी तालिका
    • साफ - सफाई

धन्यवाद, फेसबुक के दृष्टिकोण के एक "बेचा" संस्करण की तरह लगता है, जिस पर मैं और अधिक भरोसा कर सकता था ...
NeuronQ

यदि आप अपना खुद का MySQL सर्वर चला रहे हैं, तो pt-online-स्कीमा-परिवर्तन निश्चित रूप से ऐसा करने का पसंदीदा तरीका है। Percona Tools 2.2 के रूप में, (दुख की बात है) वे AWS पर RDS / Aurora का समर्थन नहीं करते हैं। pt-online-schema-change गंतव्य तालिका_temp में पंक्तियों (MyISAM के लिए कम प्राथमिकता) की प्रतिलिपि बनाने के लिए स्रोत तालिका पर एक ट्रिगर सम्मिलित करता है और एक ही त्वरित लॉकिंग ड्रॉप करता है और अंत में नाम बदलता है जब सभी पंक्तियाँ स्रोत और गंतव्य के बीच सिंक में होती हैं टेबल।
phpguru

6

सिस्टम को बंद करना और एक बार में सभी परिवर्तन करना बहुत जोखिम भरा हो सकता है। अगर कुछ गलत हो जाता है, और अक्सर ऐसा होता है, तो कोई आसान रास्ता नहीं है।

एक फुर्तीली डेवलपर के रूप में, मुझे कभी-कभी बिना किसी डाउनटाइम टेबल को रिफ्लेक्टर करने की आवश्यकता होती है, क्योंकि उन तालिकाओं को संशोधित और से पढ़ा जा रहा है।

निम्न दृष्टिकोण में कम जोखिम है, क्योंकि परिवर्तन कई कम जोखिम वाले चरणों में किया जाता है जो वापस रोल करना बहुत आसान है:

  • सुनिश्चित करें कि तालिका तक पहुँचने वाले सभी मॉड्यूल स्वचालित परीक्षणों से अच्छी तरह से कवर किए गए हैं।
  • एक नई तालिका बनाएँ। पुरानी तालिका को संशोधित करने वाली सभी प्रक्रियाओं को बदल दें, ताकि वे पुरानी और नई दोनों तालिकाओं को संशोधित कर सकें।
  • मौजूदा डेटा को नई संरचना में माइग्रेट करें। इसे स्मालिश बैचों में करें, ताकि यह सर्वर पर समग्र प्रदर्शन को गंभीरता से प्रभावित न करे।
  • सत्यापित करें कि डेटा का माइग्रेशन सफल हुआ।
  • पुरानी तालिका से नई के लिए चयन प्रक्रियाओं में से कुछ को पुनर्निर्देशित करें। यह सुनिश्चित करने के लिए स्वचालित परीक्षणों का उपयोग करें कि परिवर्तित मॉड्यूल अभी भी सही हैं। सुनिश्चित करें कि उनका प्रदर्शन स्वीकार्य है। परिवर्तित प्रक्रियाओं को लागू करें।
  • पिछले चरण को दोहराएं जब तक कि सभी रिपोर्ट नई तालिका का उपयोग न करें।
  • तालिकाओं को संशोधित करने वाली प्रक्रियाओं को बदलें, ताकि वे केवल नई तालिका तक पहुंचें।
  • पुरानी तालिका को संग्रहीत करें और इसे सिस्टम से हटा दें।

हमने इस दृष्टिकोण का उपयोग कई बार बड़े लाइव उत्पादन तालिकाओं को बिना डाउनटाइम बदलने के लिए किया है, जिसमें कोई समस्या नहीं है।


3
महान ... लेकिन यह बिल्कुल "दर्द" का प्रकार है जिससे मैं बचने के लिए देख रहा हूँ :)
NeuronQ

@NeuronQ " कोई आसान तरीका नहीं है " - पोस्टग्रेज में है: बस सब कुछ लेन-देन में डाल दें और rollbackअगर कुछ भी गलत हो जाए।
a_horse_with_no_name

2

हां, कई आधुनिक डेटाबेस आपको केवल एक कॉलम जोड़ने या एक स्तंभ की विशेषताओं को बदलने की अनुमति देंगे, जैसे कि अशक्त जोड़ने या हटाने।

यदि आप एक कॉलम छोड़ते हैं, तो डेटा खो जाएगा, लेकिन भ्रष्टाचार का बहुत डर नहीं है।


0

Percona टूल इसे बदलने में सहायता करने के लिए ट्रिगर्स का उपयोग करता है, और यह अच्छी तरह से नहीं खेलता है यदि आपकी तालिका में पहले से ही मौजूदा ट्रिगर्स हैं। मैंने एक लिखना शुरू कर दिया है जो वास्तव में मौजूदा ट्रिगर्स को अच्छी तरह से संभालता है, क्योंकि वे हमारे डेटाबेस के लिए सुपर महत्वपूर्ण हैं https://github.com/StirlingMarketingGroup/smg-live-alter


-1

ALTER TABLEकथन के साथ क्या होता है, इस सवाल के समाधान के लिए यह आपके परिवर्तनों की सीमा पर निर्भर करता है। विशिष्ट मामलों में, यदि आप एक नया स्तंभ जोड़ते हैं, तो कम से कम एमएस SQL ​​सर्वर में, इंजन तालिका की एक अस्थायी प्रतिलिपि बनाएगा, जबकि यह नई तालिका परिभाषा बनाता है, और फिर डेटा को वापस इसमें सम्मिलित करता है। परिवर्तन की अवधि के लिए, तालिका इस प्रकार उपयोगकर्ताओं के लिए दुर्गम होगी।

MSSQL सर्वर के लिए विशिष्ट संचालन का एक उदाहरण यहाँ है: http://support.microsoft.com/kb/956176/en-us

मुझे लगता है कि अन्य RMDBs के समान तरीके हैं, हालांकि सटीक कार्यान्वयन कुछ ऐसा होगा जो आपको विक्रेता प्रलेखन के साथ सत्यापित करना होगा।


-1 SQL सर्वर के लिए यह पूरी तरह से गलत है: "यदि आप एक नया कॉलम जोड़ते हैं, तो कम से कम MS SQL सर्वर में, इंजन तालिका की एक अस्थायी प्रतिलिपि बनाएगा, जबकि यह नई तालिका परिभाषा बनाता है, और फिर डेटा वापस सम्मिलित करता है। वहाँ में "
एके

@AlexKuznetsov - मैंने पूर्ववर्ती लाइन का पता लगाया, साथ ही सूचीबद्ध मामलों में से कुछ के साथ लिंक को स्पष्ट करेगा कि यह हमेशा नहीं होता है। मैंने इसे बेहतर ढंग से दर्शाने के लिए वाक्य में संशोधन किया।
SchmitzIT

1
आप GUI, SSMS के व्यवहार का उल्लेख कर रहे हैं, SQL सर्वर के व्यवहार का नहीं। आपके लिंक के बाद, सलाह है कि डीडीएल परिवर्तन करने के लिए सीधे टी-एसक्यूएल का उपयोग करें। डीडीएल को बदलने के लिए SSMS बहुत अच्छा साधन नहीं है।
एके

@AlexKuznetsov - मैंने लेख को यह कहते हुए पढ़ा कि इसमें जोखिम शामिल है, लेकिन हतोत्साहन के रूप में नहीं। वैसे भी, मैंने GUI बिट के लिए लेख को लिंक नहीं किया था, लेकिन कुछ ऑपरेशनों के संकेत के रूप में जो कि एक ALTER स्टेटमेंट की ओर ले जाते हैं, जो अंतर्निहित डेटा संरचना में परिवर्तन के कारण अस्थायी तालिका के निर्माण की ओर ले जाता है। मैंने यह परीक्षण नहीं किया है कि क्या टी-एसक्यूएल से सीधे स्टेटमेंट जारी करते समय सटीक वही बात लागू होती है, लेकिन मुझे लगता है कि यह प्रक्रिया काफी हद तक समान है और एसएल सर्वर पर्दे के पीछे का काम करता है।
श्मिटजिट

आप Profiler शुरू कर सकते हैं, सीधे टेबल विवरण निष्पादित करें और देखें कि क्या हो रहा है। फिर आप एक डायलॉग बॉक्स के माध्यम से एक टेबल को बदल सकते हैं, और अपने आप को कमांड निष्पादित होने के लिए देख सकते हैं।
एके
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.