mysql - आप विकास, परीक्षण और उत्पादन में डेटाबेस का प्रबंधन कैसे करते हैं?




svn (10)

मेरे पास विकास, परीक्षण और उत्पादन सर्वर के बीच डेटाबेस स्कीमा और डेटा को प्रबंधित करने के तरीके के अच्छे उदाहरण खोजने की कोशिश करने में एक कठिन समय है।

यहाँ हमारा सेटअप है। प्रत्येक डेवलपर के पास हमारे ऐप और MySQL डेटाबेस को चलाने वाली एक वर्चुअल मशीन होती है। यह उनका व्यक्तिगत सैंडबॉक्स है जो वे चाहते हैं। वर्तमान में, डेवलपर्स SQL ​​स्कीमा में परिवर्तन करेंगे और डेटाबेस की एक डंप को एक पाठ फ़ाइल में करेंगे जो वे एसवीएन में करते हैं।

हम एक निरंतर एकीकरण विकास सर्वर को तैनात करना चाहते हैं जो हमेशा नवीनतम प्रतिबद्ध कोड चलाएगा। यदि हम ऐसा करते हैं, तो यह प्रत्येक बिल्ड के लिए SVN से डेटाबेस को फिर से लोड करेगा।

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

जहां सब कुछ टूट जाता है उत्पादन के लिए तैनाती है। चूंकि हम परीक्षण डेटा के साथ लाइव डेटा को अधिलेखित नहीं कर सकते हैं, इसमें मैन्युअल रूप से सभी स्कीमा परिवर्तनों को फिर से बनाना शामिल है। यदि डेटा में हेरफेर करने के लिए बड़ी संख्या में स्कीमा परिवर्तन या रूपांतरण स्क्रिप्ट थे, तो यह वास्तव में बालों वाला हो सकता है।

यदि समस्या सिर्फ स्कीमा थी, तो यह एक आसान समस्या होगी, लेकिन डेटाबेस में "आधार" डेटा है जो विकास के दौरान भी अपडेट किया जाता है, जैसे कि सुरक्षा और अनुमति तालिकाओं में मेटा-डेटा।

निरंतर एकीकरण और वन-स्टेप-बिल्ड की ओर बढ़ने में यह सबसे बड़ी बाधा है। आप इसे कैसे हल करते हैं?

एक अनुवर्ती प्रश्न: आप डेटाबेस संस्करणों को कैसे ट्रैक करते हैं ताकि आप जान सकें कि किसी दिए गए डेटाबेस उदाहरण को अपग्रेड करने के लिए कौन सी स्क्रिप्ट को चलाना है? क्या मानक प्रक्रिया से नीचे लांस उल्लेखों की तरह एक संस्करण तालिका है?

टारनटिनो के संदर्भ के लिए धन्यवाद। मैं .NET वातावरण में नहीं हूँ, लेकिन मुझे उनका DataBaseChangeMangement wiki पेज बहुत मददगार लगा। विशेष रूप से यह पावरपॉइंट प्रस्तुति (.ppt)

मैं एक पायथन स्क्रिप्ट लिखने जा रहा हूं जो डेटाबेस में एक टेबल के खिलाफ एक निर्देशिका में *.sql स्क्रिप्ट के नामों की जांच करता है और उन लोगों को चलाता है जो पूर्णांक के पहले भाग को बनाने वाले पूर्णांक के आधार पर क्रम में नहीं हैं। फ़ाइल का नाम। यदि यह एक बहुत सरल समाधान है, जैसा कि मुझे संदेह है कि यह होगा, तो मैं इसे यहां पोस्ट करूंगा।

मुझे इसके लिए एक वर्किंग स्क्रिप्ट मिली है। यह DB को इनिशियलाइज़ करने का काम करता है अगर यह मौजूद नहीं है और आवश्यकतानुसार अपग्रेड स्क्रिप्ट चला रहा है। एक मौजूदा डेटाबेस को पोंछने और एक फ़ाइल से परीक्षण डेटा आयात करने के लिए स्विच भी हैं। यह लगभग 200 लाइनें है, इसलिए मैं इसे पोस्ट नहीं करूंगा (हालांकि अगर यह ब्याज है तो मैं इसे पास्टबिन पर रख सकता हूं)।


Oracle database के लिए हम oracle-ddl2svn टूल का उपयोग करते हैं

यह उपकरण स्वचालित अगली प्रक्रिया है

  1. हर db स्कीम के लिए स्कीम ddls मिलता है
  2. इसे वर्जन कंटोल के नीचे रखें

मैन्युअल रूप से हल किए गए उदाहरणों के बीच परिवर्तन


आप SQL जैसे टूल का उपयोग करके भी देख सकते हैं कि किसी डेटाबेस के विभिन्न संस्करणों के बीच के अंतर की स्क्रिप्ट की तुलना करें , जिससे आप जल्दी से संस्करणों के बीच माइग्रेट कर सकते हैं


एक नज़र डालिए कि रूबी ऑन रेल्स कैसे करती है।

पहले तथाकथित माइग्रेशन फाइलें होती हैं, जो मूल रूप से डेटाबेस स्कीमा और डेटा को एन संस्करण 1 से एन + 1 में बदल देती हैं (या संस्करण एन + 1 से एन में अपग्रेड होने की स्थिति में)। डेटाबेस में टेबल है जो वर्तमान संस्करण को बताता है।

टेस्ट डेटाबेस को हमेशा यूनिट-परीक्षणों से पहले साफ किया जाता है और फाइलों से तय आंकड़ों के साथ आबाद किया जाता है।


कुछ अच्छे विकल्प हैं। मैं "एक बैकअप को बहाल करने" की रणनीति का उपयोग नहीं करूंगा।

  1. स्क्रिप्ट आपके सभी स्कीमा में परिवर्तन करती है, और आपके CI सर्वर ने उन स्क्रिप्ट को डेटाबेस पर चलाया है। वर्तमान डेटाबेस संस्करण का ट्रैक रखने के लिए एक संस्करण तालिका है, और केवल स्क्रिप्ट को निष्पादित करें यदि वे एक नए संस्करण के लिए हैं।

  2. माइग्रेशन समाधान का उपयोग करें। ये समाधान भाषा के अनुसार भिन्न होते हैं, लेकिन .NET के लिए मैं Migrator.NET का उपयोग करता हूं। यह आपको अपने डेटाबेस को संस्करण और संस्करणों के बीच ऊपर और नीचे स्थानांतरित करने की अनुमति देता है। आपका स्कीमा C # कोड में निर्दिष्ट है।


मुझे डर है कि मैं अन्य पोस्टर के साथ समझौता कर रहा हूं। डेवलपर्स को अपने परिवर्तनों को स्क्रिप्ट करने की आवश्यकता है।

कई मामलों में एक साधारण तालिका काम नहीं करेगी, आपको मौजूदा डेटा को भी संशोधित करने की आवश्यकता है - डेवलपर्स को इस बारे में बात करने की आवश्यकता है कि माइग्रेशन की आवश्यकता क्या है और सुनिश्चित करें कि वे सही तरीके से स्क्रिप्ट किए गए हैं (निश्चित रूप से आपको किसी बिंदु पर इसे सावधानीपूर्वक परीक्षण करने की आवश्यकता है रिलीज चक्र)।

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

आप एक सीआई सर्वर में कैसे हुक करते हैं, मुझे नहीं पता। शायद आपके CI सर्वर को एक ज्ञात बिल्ड स्नैपशॉट होना आवश्यक है, जिसे वह प्रत्येक रात को पुन: प्राप्त करता है और तब से सभी परिवर्तन लागू करता है। यह शायद सबसे अच्छा है, अन्यथा एक टूटी हुई माइग्रेशन स्क्रिप्ट न केवल उस रात के निर्माण को तोड़ देगी, बल्कि सभी बाद वाले भी।


मैंने एक टूल लिखा है, जो ( ओपन डीबीडीफ में हुक करके) डेटाबेस स्कीमा की तुलना करता है, और आपको माइग्रेशन स्क्रिप्ट का सुझाव देगा। यदि आप कोई ऐसा परिवर्तन करते हैं, जो डेटा को हटाता है या संशोधित करता है, तो यह एक त्रुटि देगा, लेकिन स्क्रिप्ट के लिए एक सुझाव प्रदान करता है (उदाहरण के लिए जब नए स्कीमा में कोई स्तंभ अनुपलब्ध है, तो यह जाँच करेगा कि क्या स्तंभ का नाम बदल दिया गया है और xx बना है - उत्पन्न script.sql.suggestion (नाम बदलने वाले कथन)।

http://code.google.com/p/migrationscriptgenerator/ SQL सर्वर केवल मुझे डर है :( यह भी बहुत अल्फ़ा है, लेकिन यह बहुत कम घर्षण है (विशेषकर यदि आप इसे टारनटिनो या http://code.google.com/p/simplescriptrunner/ साथ जोड़ते हैं) http://code.google.com/p/simplescriptrunner/ )

जिस तरह से मैं इसका उपयोग करता हूं वह आपके एसएलसी में एक एसक्यूएल स्क्रिप्ट परियोजना है। आपके पास स्थानीय स्तर पर एक db_next डेटाबेस भी है जिसे आप अपने बदलाव (प्रबंधन स्टूडियो या NHibernate स्कीमा निर्यात या LinqToSql CreateDatabase या कुछ और का उपयोग करके) करते हैं। तब आप _dev और _next DBs के साथ migrationscriptgenerator निष्पादित करते हैं, जो बनाता है। एसक्यूएल अद्यतन स्क्रिप्ट भर में पलायन के लिए।


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

  • dbChanges_1.sql
  • dbChanges_2.sql
  • ...
  • dbChanges_n.sql

जब तक हम विकास की दो पंक्तियों को बनाए रखना शुरू कर देते हैं, तब तक यह अच्छी तरह से काम करता है: नए विकास के लिए ट्रंक / मेनलाइन, और बग फिक्स के लिए एक रखरखाव शाखा, अल्पकालिक संवर्द्धन आदि। अनिवार्य रूप से, शाखा में स्कीमा में परिवर्तन करने की आवश्यकता उत्पन्न हुई। इस बिंदु पर, ट्रंक में हमारे पास पहले से ही dbChanges_n + 1.sql था, इसलिए हमने निम्नलिखित की तरह एक योजना के साथ समाप्त किया:

  • dbChanges_n.1.sql
  • dbChanges_n.2.sql
  • ...
  • dbChanges_n.3.sql

फिर से, यह काफी अच्छी तरह से काम किया, जब तक कि एक दिन हमने ऊपर नहीं देखा और मेनलाइन में 42 डेल्टा स्क्रिप्ट और शाखा में 10 देखे। आह!

इन दिनों हम बस एक डेल्टा स्क्रिप्ट को बनाए रखते हैं और SVN संस्करण को देते हैं - यानी हम प्रत्येक रिलीज़ के साथ स्क्रिप्ट को ओवरराइट करते हैं। और हम शाखाओं में स्कीमा परिवर्तन करने से कतराते हैं।

इसलिए, मैं इससे संतुष्ट नहीं हूं। मुझे वास्तव में रेल से पलायन की अवधारणा पसंद है। मैं LiquiBase से काफी रोमांचित हो गया हूं । यह वृद्धिशील डेटाबेस परावर्तन की अवधारणा का समर्थन करता है। यह देखने लायक है और मैं जल्द ही इसके बारे में विस्तार से देखूंगा। किसी को भी इसके साथ अनुभव है? मैं आपके परिणामों के बारे में सुनने के लिए बहुत उत्सुक हूं।


हम कमांड-लाइन mysql-diff का उपयोग कर रहे हैं: यह ALF स्क्रिप्ट के रूप में दो डेटाबेस स्कीमा (लाइव DB या स्क्रिप्ट से) के बीच अंतर को आउटपुट करता है। mysql-diff को अनुप्रयोग प्रारंभ में निष्पादित किया जाता है, और यदि स्कीमा बदल जाता है, तो यह डेवलपर को रिपोर्ट करता है। इसलिए डेवलपर्स को ALTERs को मैन्युअल रूप से लिखने की आवश्यकता नहीं है, स्कीमा अपडेट अर्ध-स्वचालित रूप से होता है।


dbdeploy , पहले से उपलब्ध जावा और .net उपकरण हैं, आप SQL फ़ाइल लेआउट और स्कीमा संस्करण तालिका के लिए उनके मानकों का पालन कर सकते हैं और अपना पायथन संस्करण लिख सकते हैं।


  • अपने डेटाबेस को निम्नानुसार नाम दें - dev_<<db>> , tst_<<db>> , stg_<<db>> , prd_<<db>> (जाहिर है कि आपको कभी भी हार्डकोड डीबी नाम नहीं चाहिए
  • इस प्रकार आप एक ही भौतिक सर्वर पर db के विभिन्न प्रकारों को भी तैनात करने में सक्षम होंगे (मैं इसकी अनुशंसा नहीं करता, लेकिन आपके पास हो सकता है ... यदि संसाधन तंग हैं)
  • सुनिश्चित करें कि आप स्वचालित रूप से उन लोगों के बीच डेटा स्थानांतरित करने में सक्षम होंगे
  • Db निर्माण स्क्रिप्ट को जनसंख्या से अलग करें = db को स्क्रैच से फिर से बनाना और इसे पॉप्युलेट करना (पुराने db संस्करण या बाहरी डेटा स्रोत से) हमेशा संभव होना चाहिए
  • कोड में हार्डकोड कनेक्शन स्ट्रिंग्स का उपयोग न करें (यहां तक ​​कि कॉन्फ़िगरेशन फ़ाइलों में भी नहीं) - कॉन्फिग फाइलों में उपयोग करें कनेक्शन स्ट्रिंग टेम्पलेट, जो आप गतिशील रूप से पॉप्युलेट करते हैं, application_layer के प्रत्येक पुनर्संरचना की आवश्यकता होती है जिसे recompile की आवश्यकता होती है BAD
  • डेटाबेस वर्जनिंग और डीबी ऑब्जेक्ट्स वर्जनिंग का उपयोग करें - यदि आप इसे तैयार कर सकते हैं तो तैयार उत्पादों का उपयोग कर सकते हैं, यदि आपके पास कुछ नहीं है
  • प्रत्येक डीडीएल परिवर्तन को ट्रैक करें और इसे कुछ इतिहास तालिका में सहेजें ( उदाहरण के लिए )
  • दैनिक बैकअप! परीक्षण करें कि आप बैकअप से खोई हुई किसी चीज़ को कितनी जल्दी पुनर्स्थापित कर पाएंगे (ऑटोमैटिक रिस्टोर स्क्रिप्ट्स का उपयोग करें)
  • यहां तक ​​कि आपके डीईवी डेटाबेस और पीआरडी के पास एक ही निर्माण स्क्रिप्ट है, जिसमें आपको डेटा की समस्या होगी, इसलिए डेवलपर्स को ठेस की सटीक प्रतिलिपि बनाने और इसके साथ खेलने की अनुमति दें (मुझे पता है कि मैं इस एक के लिए minuses प्राप्त करूंगा, लेकिन परिवर्तन मानसिकता और व्यवसाय प्रक्रिया आपको बहुत कम खर्च करेगी जब गंदगी पंखे से टकराएगी - तो कोडर्स को कानूनी रूप से जो कुछ भी बनाता है उसे सब्सक्राइब करने के लिए मजबूर करें, लेकिन यह सुनिश्चित करें




svn