एक प्रोडक्शन PostgreSQL डिप्लॉयमेंट क्रैश हो गया क्योंकि एक डेवलपर ने CREATE OR REPLACE FUNCTION का उपयोग करके एक मौजूदा फंक्शन में एक वैकल्पिक तर्क (optional argument) जोड़ दिया था। इस बदलाव के कारण एक ही नाम के दो फंक्शन बन गए, जिससे डेटाबेस ने “function is not unique” एरर दिया और API ने 400 एरर भेजा। यह घटना दर्शाती है कि कैसे माइग्रेशन की एक छोटी सी गलती चुपचाप एक लाइव स्कीमा को दूषित कर सकती है और क्यों केवल कोड-लेवल चेक पर्याप्त नहीं हैं।
What went wrong
टीम को एक स्टॉयड प्रोसीजर (stored procedure) में एक अतिरिक्त, वैकल्पिक पैरामीटर जोड़ने की आवश्यकता थी। उन्होंने यह मानकर CREATE OR REPLACE FUNCTION … चलाया कि यह पुराने डेफिनिशन को ओवरराइट कर देगा। PostgreSQL किसी फंक्शन को तभी रिप्लेस करता है जब उसकी पूरी आर्गुमेंट लिस्ट (argument list) बिल्कुल मेल खाती हो। सिग्नेचर बदलने से एक बिल्कुल नया फंक्शन एंट्री बन जाता है, जबकि मूल फंक्शन वैसा ही रहता है।
चूंकि नए आर्गुमेंट में एक डिफॉल्ट वैल्यू थी, इसलिए जो कॉलर्स पुराने आर्गुमेंट की संख्या भेज रहे थे, वे दोनों में से किसी भी डेफिनिशन से मेल खा सकते थे। PostgreSQL यह तय नहीं कर सका कि किसे कॉल करना है और उसने “function is not unique” एरर दे दिया, जो API से 400 रिस्पॉन्स के रूप में सामने आया।
कोड रिपॉजिटरी में केवल एक ही डेफिनिशन दिख रही थी, और सोर्स ट्री को स्कैन करने वाले एक कस्टम स्क्रिप्ट ने कोई डुप्लिकेट नहीं पाया। डुप्लिकेट केवल डेटाबेस में मौजूद था, जो तब आया जब सर्वर पर एक पुरानी माइग्रेशन फाइल को दोबारा चलाया गया था।
Why the migration slipped through
जिस माइग्रेशन ने वैकल्पिक पैरामीटर जोड़ा था, उसने बस CREATE OR REPLACE FUNCTION चलाया। जब माइग्रेशन दूसरी बार चला—शायद रोलबैक के बाद या रिपीट डिप्लॉयमेंट के दौरान—तो डेटाबेस ने इस कमांड को “मौजूदा वाले को रिप्लेस करने” के बजाय “एक नया ओवरलोड जोड़ने” के रूप में माना। माइग्रेशन ने परिणामी स्थिति (resulting state) को सत्यापित नहीं किया, इसलिए डुप्लिकेट बिना किसी जानकारी के बना रहा।
रिपॉजिटरी की जांच करने वाली स्क्रिप्ट ने सोर्स फाइलों की जांच की थी, लाइव स्कीमा की नहीं। वह सामने के दरवाजे को देख रही थी जबकि बग पीछे के दरवाजे से अंदर आ गया था।
The stakes
एक अकेला अस्पष्ट (ambiguous) फंक्शन उस किसी भी सर्विस को डाउन कर सकता है जो उस पर निर्भर है। समाधान में यह शामिल था कि यदि फंक्शन की संख्या गलत हो तो ट्रांजेक्शन को रोलबैक किया जाए और स्कीमा कैश को रीलोड करने के लिए सूचित किया जाए।
How to safeguard migrations
टीम ने स्पष्ट चेक्स के साथ माइग्रेशन को फिर से बनाया, जिससे यह एक सेल्फ-असर्टिंग ऑपरेशन बन गया:
- एक ट्रांजेक्शन शुरू करें (Start a transaction) ताकि किसी भी विफलता की स्थिति में पूरा बदलाव रोलबैक हो जाए।
- पुराने फंक्शन को स्पष्ट रूप से ड्रॉप करें (Drop the old function explicitly) नए वर्जन को बनाने से पहले, ताकि यह सुनिश्चित हो सके कि केवल एक ही डेफिनिशन मौजूद है।
- नया फंक्शन बनाएं (Create the new function) वांछित सिग्नेचर के साथ।
- फंक्शन्स की गिनती करें (Count the functions)
pg_catalogमें दिए गए नाम के साथ और सत्यापित करें कि गिनती ठीक एक है। - ट्रांजेक्शन को रोलबैक करें (Roll back) यदि गिनती अलग हो, ताकि डुप्लिकेट बना न रहे।
- स्कीमा कैश को सूचित करें (Notify the schema cache) ताकि वह रीलोड हो सके, जिससे यह सुनिश्चित हो सके कि बाद की क्वेरीज़ अपडेटेड डेफिनिशन को देखें।
कोड सही होने का अनुमान लगाने के बजाय डेटाबेस से यह पूछकर कि “कौन से फंक्शन मौजूद हैं?”, माइग्रेशन बार-बार चलाने, आंशिक डिप्लॉयमेंट या मैन्युअल एडिटिंग के खिलाफ विश्वसनीय बन जाता है।
Counter-argument: convenience vs. safety
CREATE OR REPLACE FUNCTION आकर्षक है क्योंकि यह डेवलपर्स को अलग से ड्रॉप स्टेटमेंट लिखे बिना तेज़ी से इटरेशन करने की अनुमति देता है। उन वातावरणों में जहाँ माइग्रेशन केवल एक बार चलते हैं और दोबारा नहीं चलते, यह शॉर्टकट ठीक काम करता है। जोखिम तब आता है जब माइग्रेशन को दोबारा चलाया जाता है—चाहे वह CI पाइपलाइन्स के कारण हो जो टेस्ट डेटाबेस को रीसेट करती हैं, ऑटोमेटेड रोलबैक के कारण, या प्रोडक्शन में मैन्युअल री-एप्लीकेशन के कारण।
Takeaway
CREATE OR REPLACE के साथ फंक्शन के सिग्नेचर को बदलना रिप्लेसमेंट की गारंटी नहीं देता—यदि आर्गुमेंट लिस्ट अलग है, तो PostgreSQL चुपचाप एक ओवरलोड बना देगा। जो प्रोडक्शन वातावरण माइग्रेशन पर निर्भर हैं, उन्हें केवल सोर्स कोड ही नहीं, बल्कि परिणामी स्कीमा को भी सत्यापित करना चाहिए। स्पष्ट ड्रॉप्स, ट्रांजेक्शनल चेक्स और पोस्ट-माइग्रेशन एसर्शन को शामिल करने से एक सुविधाजनक शॉर्टकट एक विश्वसनीय और दोहराने योग्य प्रक्रिया में बदल जाता है।
