सीखें कि Claude Code के साथ PostgreSQL माइग्रेशन कैसे सुरक्षित रूप से करें: expand/contract पैटर्न, बैकफिल और रोलबैक प्लान, और रिलीज़ से पहले स्टेजिंग में क्या वेरिफाई करना चाहिए।

PostgreSQL स्कीमा बदलना साधारण दिखता है—जब तक वह असली ट्रैफ़िक और असली डेटा से नहीं मिलता। जोखिम आमतौर पर SQL ही नहीं होता; असल समस्या तब आती है जब आपका एप कोड, डेटाबेस की स्थिति, और डिप्लॉयमेंट टाइमिंग मेल नहीं खाते।
अधिकांश विफलताएँ व्यावहारिक और दर्दनाक होती हैं: एक डिप्लॉय टूट जाता है क्योंकि पुराना कोड नए कॉलम को देखता है, एक migration किसी हॉट टेबल पर लॉक कर देता है और टाइमआउट बढ़ जाते हैं, या एक “तेज़” बदलाव चुपचाप डेटा ड्रॉप या री-राइट कर देता है। जब कुछ क्रैश नहीं भी होता, तब भी आप सूक्ष्म बग भेज सकते हैं—गलत डिफॉल्ट, टूटे कंस्ट्रेंट, या ऐसे इंडेक्स जो बिल्ड भी नहीं हुए।
AI-जनित migrations एक और जोखिम जोड़ते हैं। टूल वैध SQL बना सकते हैं जो आपकी वर्कलोड, डेटा वॉल्यूम, या रिलीज़ प्रोसेस के लिए असुरक्षित हो सकता है। वे टेबल नामों का अनुमान लगा सकते हैं, लंबी चलने वाली लॉक को मिस कर सकते हैं, या रोलबैक को हल्का कर सकते हैं क्योंकि डाउन migrations कठिन होते हैं। यदि आप Claude Code का उपयोग कर रहे हैं, तो आपको गार्डरेलों और ठोस संदर्भ की ज़रूरत है।
जब इस पोस्ट में कोई बदलाव "सुरक्षित" कहा जाता है, तो इसका मतलब तीन चीज़ें हैं:
लक्ष्य यह है कि migrations सामान्य काम बन जाएँ: पूर्वानुमेय, टेस्टेबल, और नीरस।
कुछ अनिवार्य नियमों के साथ शुरू करें। वे मॉडल को केंद्रित रखते हैं और आपको ऐसे बदलाव भेजने से रोकते हैं जो सिर्फ आपके लैपटॉप पर काम करते हैं।
काम को छोटे चरणों में विभाजित करें। एक स्कीमा बदलाव, एक डेटा बैकफिल, एक एप बदलाव, और एक cleanup स्टेप अलग जोखिम हैं। इन्हें एक साथ बांधने से यह देखना मुश्किल हो जाता है कि क्या टूटा और रोलबैक और भी कठिन हो जाता है।
विनाशकारी चीजों की बजाय बढ़ाने वाले (additive) बदलाव प्राथमिकता दें। कॉलम, इंडेक्स, या टेबल जोड़ना आमतौर पर कम जोखिम होता है। नाम बदलना या ऑब्जेक्ट्स हटाना वही जगह है जहाँ आउटेज होते हैं। पहले सुरक्षित हिस्सा करें, एप को बदलें, और तब ही पुराना हटाएँ जब आप सुनिश्चित हों कि वह अनयूज्ड है।
एप को थोड़ी देर दोनों शेप सहन करने योग्य बनाएं। कोड को पुराने कॉलम या नए दोनों को पढ़ सकना चाहिए रोलआउट के दौरान। इससे वह सामान्य रेस बचता है जहाँ कुछ सर्वर नया कोड चला रहे होते हैं जबकि डेटाबेस अभी पुराना है (या इसके विपरीत)।
माइग्रेशन को एक तेज़ स्क्रिप्ट की तरह न मानें—उन्हें प्रोडक्शन कोड की तरह ट्रीट करें। भले ही आप किसी प्लेटफ़ॉर्म जैसे Koder.ai (Go बैकएंड with PostgreSQL, plus React or Flutter clients) के साथ बना रहे हों, डेटाबेस सब कुछ साझा करता है। गलतियाँ महंगी होती हैं।
यदि आप हर SQL रिक्वेस्ट के ऊपर नियमों का एक कॉम्पैक्ट सेट डालना चाहते हैं, तो कुछ ऐसा रखें:
एक व्यावहारिक उदाहरण: जिस कॉलम पर आपका एप निर्भर करता है उसे rename करने के बजाय, नया कॉलम जोड़ें, उसे धीरे-धीरे backfill करें, नया पढ़ने वाला कोड डिप्लॉय करें जो नया पढ़े फिर पुराना, और तभी पुराना कॉलम हटाएँ जब सुनिश्चित हो कि वह उपयोग में नहीं है।
Claude अस्पष्ट अनुरोध से ठीक-ठाक SQL लिख सकता है, पर सुरक्षित migrations को संदर्भ चाहिए। अपने प्रॉम्प्ट को एक लघु डिजाइन ब्रिफ की तरह रखें: क्या मौजूद है दिखाएँ, क्या नहीं टूटना चाहिए बताएं, और रोलआउट के लिए "सुरक्षित" का अर्थ परिभाषित करें।
सबसे पहले केवल वही डेटाबेस फैक्ट्स पेस्ट करें जो मायने रखते हैं। तालिका परिभाषा के साथ संबंधित इंडेक्स और कंस्ट्रेंट (प्राइमरी कीज़, यूनिक, फॉरेन की, चेक कंस्ट्रेंट, ट्रिगर्स) शामिल करें। यदि संबंधित टेबल हैं, तो उनके स्निपेट भी दें। एक छोटा, सटीक एक्स्ट्रैक्ट मॉडल को नामों का अनुमान लगाने या महत्वपूर्ण कंस्ट्रेंट मिस करने से रोकेगा।
वास्तविक दुनिया का स्केल जोड़ें। रो काउंट्स, टेबल साइज, write दर, और पीक ट्रैफ़िक प्लान बदल देते हैं। "200M rows and 1k writes/sec" एक अलग migration है बनाम "20k rows and mostly reads." साथ ही अपना Postgres वर्ज़न और आपकी सिस्टम में migrations कैसे चलते हैं (सिंगल ट्रांज़ैक्शन बनाम कई स्टेप) बताएं।
बताएँ कि एप डेटा का उपयोग कैसे करता है: महत्वपूर्ण पढ़ाइयां, लिखाइयां, और बैकग्राउंड जॉब्स। उदाहरण: "API reads by email," "workers update status," या "reports scan by created_at." यह तय करता है कि आपको expand/contract, फीचर फ़्लैग्स, और backfill कितना सुरक्षित चाहिए।
अंत में, कड़ाई से constraints और deliverables पर स्पष्ट हों। एक सादा स्ट्रक्चर अच्छा रहता है:
SQL और रन प्लान दोनों मांगने से मॉडल को क्रम, जोखिम, और शिप करने से पहले क्या चेक करना है इसकी सोचने के लिए मजबूर किया जाता है।
Expand/contract migration पैटर्न PostgreSQL डेटाबेस में ऐसे बदलाव करता है कि ऐप बीच में नहीं टूटे। एक ही जोखिम भरे स्विच की जगह, आप डेटाबेस को थोड़ी देर के लिए पुराने और नए दोनों शेप सपोर्ट करने देते हैं।
इसे ऐसे समझें: नए हिस्से सुरक्षित रूप से जोड़ें (expand), ट्रैफिक और डेटा धीरे-धीरे मूव करें, और केवल तब पुरानी चीज़ें हटाएँ (contract)। यह AI-सहायता वाले काम के लिए खासकर उपयोगी है क्योंकि यह आपको बीच के गंदे हिस्से की योजना बनाना मजबूरी कर देता है।
एक व्यावहारिक फ्लो कुछ इस तरह दिखता है:
यह पैटर्न तब उपयोग करें जब यूज़र्स अभी भी पुराने एप कोड पर हो सकते हैं—multi-instance deployments, मोबाइल ऐप जो धीरे-धीरे अपडेट होते हैं, या कोई भी रिलीज़ जहाँ migration मिनटों या घंटों तक चल सकता है।
एक मददगार तरकीब है दो रिलीज़ का प्लान बनाना। रिलीज 1 में expand और compatibility करें ताकि अगर backfill अधूरा भी रहे तो कुछ न टूटे। रिलीज 2 में contract करें केवल तब जब आप कन्फर्म कर लें कि नया कोड और नया डेटा inplace है।
Copy करें यह टेम्पलेट और ब्रैकेट्स भरें। यह Claude Code को SQL देने के साथ-साथ रन प्लान, वेरिफिकेशन, और रोलबैक पर भी दबाव डालेगा।
You are helping me plan a PostgreSQL expand-contract migration.
Context
- App: [what the feature does, who uses it]
- Database: PostgreSQL [version if known]
- Table sizes: [rough row counts], write rate: [low/medium/high]
- Zero/near-zero downtime required: [yes/no]
Goal
- Change: [describe the schema change]
- Current schema (relevant parts):
[paste CREATE TABLE or \d output]
- How the app will change (expand phase and contract phase):
- Expand: [new columns/indexes/triggers, dual-write, read preference]
- Contract: [when/how we stop writing old fields and remove them]
Hard safety requirements
- Prefer lock-safe operations. Avoid full table rewrites on large tables when possible.
- If any step can block writes, call it out explicitly and suggest alternatives.
- Use small, reversible steps. No “big bang” changes.
Deliverables
1) UP migration SQL (expand)
- Use clear comments.
- If you propose indexes, tell me if they should be created CONCURRENTLY.
- If you propose constraints, tell me whether to add them NOT VALID then VALIDATE.
2) Verification queries
- Queries to confirm the new schema exists.
- Queries to confirm data is being written to both old and new structures (if dual-write).
- Queries to estimate whether the change caused bloat/slow queries/locks.
3) Rollback plan (realistic)
- DOWN migration SQL (only if it is truly safe).
- If down is not safe, write a rollback runbook:
- how to stop the app change
- how to switch reads back
- what data might be lost or need re-backfill
4) Runbook notes
- Exact order of operations (including app deploy steps).
- What to monitor during the run (errors, latency, deadlocks, lock waits).
- “Stop/continue” checkpoints.
Output format
- Separate sections titled: UP.sql, VERIFY.sql, DOWN.sql (or ROLLBACK.md), RUNBOOK.md
दो अतिरिक्त लाइनें जो व्यावहारिक तौर पर मदद करती हैं:
RISK: blocks writes के रूप में लेबल करने के लिए कहें, और कब चलाना है (off-peak vs anytime)।छोटे स्कीमा बदलाव भी तब तक हानिकारक हो सकते हैं जब तक वे लंबी लॉक लेते हैं, बड़े टेबल को री-राइट करते हैं, या बीच में फेल हो जाते हैं। Claude Code का उपयोग करते समय सुरक्षित SQL माँगे जो री-राइट से बचे और आपका एप तब तक काम करता रहे जब तक डेटाबेस catch up हो रहा है।
एक nullable कॉलम जोड़ना आमतौर पर सुरक्षित है। non-null डिफ़ॉल्ट के साथ कॉलम जोड़ना पुराने Postgres वर्ज़नों पर जोखिम भरा हो सकता है क्योंकि यह पूरे टेबल को री-राइट कर सकता है।
एक सुरक्षित तरीका दो स्टेप का है: कॉलम को NULL के साथ जोड़ें बिना डिफ़ॉल्ट के, बैच में backfill करें, फिर नए रो के लिए डिफ़ॉल्ट सेट करें और डेटा साफ होने पर NOT NULL लगाएँ।
यदि आपको तुरंत डिफ़ॉल्ट लागू करना ही है, तो अपने Postgres वर्ज़न के लिए लॉक व्यवहार का स्पष्टीकरण और लंबा रन होने पर फॉलबैक प्लान माँगे।
बड़े टेबल पर इंडेक्स के लिए CREATE INDEX CONCURRENTLY मांगें ताकि रीड और राइट चलते रहें। साथ में यह नोट भी माँगे कि यह ट्रांज़ैक्शन ब्लॉक के अंदर नहीं चल सकता, मतलब आपकी migration टूलिंग को एक non-transactional स्टेप चाहिए।
फॉरेन कीज़ के लिए सुरक्षित रास्ता आमतौर पर पहले कंस्ट्रेंट को NOT VALID के रूप में जोड़ना और बाद में validate करना है। इससे शुरुआती बदलाव तेज़ रहता है जबकि नए राइट्स पर FK लागू रहता है।
जब आप कंस्ट्रेंट्स को सख्त कर रहे हों (NOT NULL, UNIQUE, CHECK), तो "पहले साफ़ करें, फिर लागू करें" माँगे। माइग्रेशन को बुरा रो पता लगाना चाहिए, उन्हें ठीक करना चाहिए, और तभी सख्ती सक्षम करनी चाहिए।
ऑब्जेक्ट्स को तब ही ड्रॉप करें जब एक पूरा रिलीज़ साइकिल गुजर जाए और यह कन्फर्म हो कि कोई उन्हें नहीं पढ़ रहा।
एक छोटा चेकलिस्ट जो आप प्रॉम्प्ट में पेस्ट कर सकते हैं:
बैकफिल्स वह जगह है जहाँ अधिकतर माइग्रेशन दर्द दिखता है, न कि ALTER TABLE। सुरक्षित प्रॉम्प्ट बैकफिल्स को कंट्रोल्ड जॉब्स की तरह ट्रीट करते हैं: मापने योग्य, restartable, और प्रोडक्शन पर धीरे-धीरे असर डालने वाले।
शुरूआत ऐसे acceptance checks से करें जो चलाने में आसान और विवाद के लिए कठिन हों: अपेक्षित रो काउंट्स, लक्षित null दर, और कुछ spot checks (उदा., पुराने बनाम नए मानों की 20 रैंडम IDs की तुलना)।
फिर बैचिंग प्लान माँगे। बैच लॉक को छोटा रखते हैं और सरप्राइज़ घटाते हैं। अच्छा अनुरोध बताता है:
idempotency अनिवार्य करें क्योंकि बैकफिल बीच में फेल होता है। SQL दुबारा चलाने पर डुप्लिकेट या करप्ट न करे। सामान्य पैटर्न हैं "update केवल जहाँ new column NULL है" या डिटरमिनिस्टिक नियम जहाँ वही इनपुट हमेशा वही आउटपुट देगा।
साथ ही यह लिखें कि बैकफिल चलते समय एप कैसे सही रहेगा। नए लिखने लगातार हो रहे हैं तो आपको ब्रिज चाहिए: एप को dual-write करना, अस्थायी ट्रिगर, या read-fallback लॉजिक। बताइए कौन सा तरीका आप सुरक्षित रूप से डिप्लॉय कर सकते हैं।
अंत में, pause और resume डिज़ाइन में बनाएं। प्रोग्रेस ट्रैकिंग और checkpoints जैसे एक छोटी टेबल रखें जो last processed ID स्टोर करे और एक क्वेरी जो प्रगति रिपोर्ट करे (rows updated, last ID, start time)।
उदाहरण: आप users.full_name जोड़ते हैं जो first_name और last_name से बनता है। एक सुरक्षित बैकफिल केवल उन रोज़ को अपडेट करे जहां full_name IS NULL, ID रेंज में चले, last updated ID रिकॉर्ड करे, और नए साइनअप्स dual-write के जरिये सही रहें जब तक स्विच-ओवर पूरा न हो।
रोलबैक प्लान सिर्फ "down migration लिखो" नहीं होता। यह दो समस्याएँ हैं: स्कीमा बदलाव को उलटना और उस डेटा को हैंडल करना जो नए वर्ज़न के लाइव होने के दौरान बदल गया। स्कीमा रोलबैक अक्सर संभव है। डेटा रोलबैक अक्सर नहीं, जब तक आपने पहले से योजना न बनाई हो।
रोलबैक का अर्थ क्या है—इस पर स्पष्ट रहें। यदि आप कॉलम ड्रॉप कर रहे हैं या इन-प्लेस वैल्यूज़ री-राइट कर रहे हैं, तो एक वास्तविक उत्तर माँगे जैसे: "Rollback एप कंपैटिबिलिटी बहाल करता है, पर मौलिक डेटा बिना स्नैपशॉट के वापस नहीं आएगा।" यह ईमानदारी ही आपको सुरक्षित रखती है।
रोलबैक ट्रिगर्स स्पष्ट माँगे ताकि किसी घटना के दौरान बहस न हो। उदाहरण:
पूरा रोलबैक पैकेज माँगे, सिर्फ SQL नहीं: down migration SQL (सिर्फ अगर सुरक्षित हो), एप स्टेप्स जो कम्पैटिबिलिटी बनाये रखते हैं, और बैकग्राउण्ड जॉब्स को कैसे रोकना है।
यह प्रॉम्प्ट पैटर्न अक्सर काफी होता है:
Produce a rollback plan for this migration.
Include: down migration SQL, app config/code switches needed for compatibility, and the exact order of steps.
State what can be rolled back (schema) vs what cannot (data) and what evidence we need before deciding.
Include rollback triggers with thresholds.
शिप करने से पहले एक हल्का "safety snapshot" कैप्चर करें ताकि आप पहले और बाद की तुलना कर सकें:
यह भी स्पष्ट रखें कि कब रोलबैक नहीं करना चाहिए। यदि आपने सिर्फ एक nullable कॉलम जोड़ा है और एप dual-writing कर रहा है, तो आगे बढ़कर फिक्स करना (hotfix कोड, backfill रोकना, फिर resume) अक्सर revert करने से सुरक्षित होता है।
AI तेजी से SQL लिख सकता है, पर वह आपका प्रोडक्शन डेटाबेस नहीं देख सकता। अधिकतर विफलताएँ तब होती हैं जब प्रॉम्प्ट अस्पष्ट होता है और मॉडल गेप्स भर देता है।
एक सामान्य फंदा करंट स्कीमा छोड़ना है। अगर आप टेबल डिफिनिशन, इंडेक्स, और कंस्ट्रेंट पेस्ट नहीं करते, तो SQL ऐसे कॉलम को टार्गेट कर सकता है जो मौजूद नहीं है या एक यूनिक नियम मिस करके बैकफिल को लॉक-भारी बना सकता है।
एक और गलती expand, backfill, और contract को एक ही डिप्लॉय में भेजना है। इससे आपकी एस्केप हैच हट जाती है। अगर बैकफिल लंबा चले या बीच में एरर करे, तो आप ऐसे एप के साथ फंसे रहेंगे जो अंतिम स्टेट की उम्मीद करता है।
सबसे आम समस्याएँ:
एक ठोस उदाहरण: "कॉलम का नाम बदलो और एप अपडेट करो." अगर जनरेटेड प्लान नाम बदलता और बैकफिल एक ही ट्रांज़ैक्शन में करता है, तो एक धीमा बैकफिल लॉक पकड़ सकता है और लाइव ट्रैफ़िक तोड़ सकता है। एक सुरक्षित प्रॉम्प्ट छोटे बैच, स्पष्ट टाइमआउट, और contract से पहले verification क्वेरीज मजबूर करेगा।
स्टेजिंग वह जगह है जहाँ आप छोटी dev DB पर कभी न दिखने वाली समस्याएँ पाते हैं: लंबे लॉक, आश्चर्यजनक nulls, गायब इंडेक्स, और भूले हुए कोड पाथ।
सबसे पहले चेक करें कि माइग्रेशन के बाद स्कीमा योजना से मेल खाता है: कॉलम्स, प्रकार, डिफ़ॉल्ट, कंस्ट्रेंट्स, और इंडेक्स। एक त्वरित नज़र पर्याप्त नहीं है। एक मिसिंग इंडेक्स पूरा बैकफिल को धीमा कर सकता है।
फिर वास्तविकडेटासेट के साथ माइग्रेशन चलाएँ। आदर्श रूप में यह प्रोडक्शन डेटा की हालिया कॉपी हो, संवेदनशील फील्ड्स मास्क करते हुए। अगर आप ऐसा नहीं कर सकते, तो कम-से-कम प्रोडक्शन वॉल्यूम और हॉटस्पॉट्स (बड़ी टेबल्स, वाइड रोज़, भारी इंडेक्स्ड टेबल्स) मिलाने की कोशिश करें। हर स्टेप का टायमिंग रिकॉर्ड करें ताकि आप प्रोडक्शन में क्या अपेक्ष करें जानें।
एक संक्षिप्त स्टेजिंग चेकलिस्ट:
अंत में, केवल SQL नहीं—रियल यूज़र फ्लोज़ टेस्ट करें। बनाएँ, अपडेट करें, और वे रिकॉर्ड पढ़ें जो बदलाव से प्रभावित हैं। यदि expand/contract योजना है, तो पुष्टि करें कि दोनों स्कीमा तब तक काम करते हैं जब तक क्लीनअप नहीं होता।
मान लीजिए आपके पास users.name कॉलम है जो पूरा नाम स्टोर करता है जैसे "Ada Lovelace." आप first_name और last_name चाहतें हैं, पर आप साइनअप्स, प्रोफ़ाइल्स, या एडमिन स्क्रीन को रोलआउट के दौरान नहीं तोड़ना चाहते।
पहले एक expand स्टेप से शुरू करें जो सुरक्षित हो चाहे कोई कोड चेंज शिप न भी हुआ हो: nullable कॉलम जोड़ें, पुराना कॉलम रखें, और लंबी लॉक से बचें।
ALTER TABLE users ADD COLUMN first_name text;
ALTER TABLE users ADD COLUMN last_name text;
फिर एप बिहेवियर बदलें ताकि दोनों स्कीमा सपोर्ट हों। रिलीज 1 में एप को नया कॉलम मौजूद होने पर उससे पढ़ना चाहिए, वरना name से fallback करना चाहिए, और दोनों जगह लिखना चाहिए ताकि नया डेटा consistent रहे।
अगला बैकफिल है। एक बैच जॉब चलाएँ जो प्रति रन छोटे चंक्स अपडेट करे, प्रगति रिकॉर्ड करे, और सुरक्षित रूप से pause किया जा सके। उदाहरण के लिए: ascending ID order में first_name null वाले users को 1,000-1,000 करके अपडेट करें और लॉग करें कि कितनी रो बदलीं।
कड़े नियम लगाने से पहले स्टेजिंग में validate करें:
first_name और last_name भरता है और अभी भी name सेट होता हैname मौजूद होusers पर बेसिक क्वेरीज नोटिसेबल रूप से धीमी नहीं हुईंरिलीज 2 रीड्स को केवल नए कॉलम से पढ़ता है। केवल तभी constraints (जैसे SET NOT NULL) जोड़ें और name हटाएँ, और वह भी किसी बाद की अलग डिप्लॉय में।
रोलबैक के लिए, चीज़ें साधारण रखें। ट्रांज़िशन के दौरान एप name पढ़ता रहे, और बैकफिल pausible हो। अगर आपको रिलीज 2 वापस लेना हो, तो पढ़ाई वापस name पर स्विच करें और नए कॉलम वहीं छोड़ दें जब तक आप फिर से स्थिर नहीं हैं।
हर बदलाव को एक छोटे रनबुक की तरह ट्रीट करें। लक्ष्य एक परफेक्ट प्रॉम्प्ट नहीं है—एक रूटीन है जो सही विवरण मांगे: स्कीमा, कंस्ट्रेंट्स, रन प्लान, और रोलबैक।
फैसला करें कि हर माइग्रेशन रिक्वेस्ट में क्या-क्या अनिवार्य होगा:
पहले से तय करें कि हर स्टेप किसका है ताकि "हर कोई सोचता रहा कोई और कर रहा है" जैसी स्थिति न बने: डेवलपर्स प्रॉम्प्ट और माइग्रेशन कोड के मालिक हों, ऑप्स प्रोडक्शन के समय और मॉनिटरिंग के मालिक हों, QA स्टेजिंग व्यवहार और एज केस वेरिफाई करे, और एक व्यक्ति फाइनल गो/नो-गो का जिम्मेदार हो।
यदि आप चैट के जरिए ऐप बना रहे हैं, तो SQL जनरेट करने से पहले क्रम को रेखांकित करना मददगार होता है। Koder.ai उपयोग करने वाली टीमों के लिए, Planning Mode प्राकृतिक जगह है यह क्रम लिखने की, और स्नैपशॉट्स व रोलबैक ब्लास्ट रेडियस कम कर सकते हैं यदि रोलआउट के दौरान कुछ अनअपेक्षित होता है।
शिप करने के बाद, क्लीनअप (contract) को तुरंत शेड्यूल करें ताकि पुराना कॉलम और अस्थायी कंपैटिबिलिटी कोड महीनों तक न टिका रहे।
ऐसा तब होता है जब एप कोड, डेटाबेस की स्थिति, और डिप्लॉयमेंट का समय मेल नहीं खाते।
सामान्य विफलताएँ:
एक expand/contract विधि का उपयोग करें:
यह रोलआउट के दौरान पुराने और नए दोनों एप वर्ज़न काम करते रहने देता है।
मॉडल ऐसा SQL बना सकता है जो वैध तो दिखे पर आपके वर्कलोड के लिए असुरक्षित हो।
AI-विशेष जोखिम:
AI आउटपुट को ड्राफ्ट मानें और रन प्लान, चेक्स, और रोलबैक स्टेप्स माँगे।
केवल वही तथ्य पेस्ट करें जिनपर migration निर्भर करता है:
CREATE TABLE स्निपेट्स (इंडेक्स, FKs, UNIQUE/CHECK, ट्रिगर्स सहित)डिफ़ॉल्ट नियम: विन्यास और बैकफ़िल अलग रखें।
एक व्यावहारिक विभाजन:
सब कुछ एक साथ बंडल करने से फेल होना और रोलबैक मुश्किल हो जाता है।
निम्न पद्धति अपनाएँ:
ADD COLUMN ... NULL बिना डिफ़ॉल्ट के (तेज़)NOT NULL जोड़ेंकुछ Postgres वर्ज़नों पर तुरंत non-null default सेट करना पूरे टेबल को री-राइट कर सकता है। यदि तुरंत डिफ़ॉल्ट चाहिए तो लॉक/रनटाइम के नोट और सुरक्षित फॉलबैक माँगे।
निम्न माँगे:
CREATE INDEX CONCURRENTLYवेरिफिकेशन के लिए, स्टेजिंग में इंडेक्स मौजूद है और उपयोग हो रहा है यह जल्दी से चेक करें (उदा., EXPLAIN प्लान की तुलना)।
पहले NOT VALID के रूप में FK जोड़ें, फिर बाद में validate करें:
NOT VALID रखें ताकि शुरुआती स्टेप कम disruptive होयह नए writes पर FK लागू रखता है, जबकि महँगी validation को आपने नियंत्रित समय पर किया होता है।
एक अच्छा backfill होना चाहिए: बैच्ड, idempotent, और restartable।
व्यवहारिक आवश्यकताएँ:
WHERE new_col IS NULL)डिफ़ॉल्ट रोलबैक लक्ष्य: तेज़ एप कम्पैटिबिलिटी बहाल करना, भले ही डेटा पूरी तरह वापस न हो सके।
एक काम करने योग्य रोलबैक प्लान में शामिल हो:
अक्सर सबसे सुरक्षित रोलबैक पुराने फ़ील्ड पर पढ़ना वापस स्विच करना है जबकि नए कॉलम बने रहें।
यह अनुमान लगाने से बचाता है और सही क्रम को मजबूर करता है।
यह बैकफिल वास्तविक ट्रैफ़िक में टिके रहना संभव बनाता है।