ஒரு டெவலப்பர் ஏற்கனவே உள்ள ஒரு செயல்பாட்டிற்கு (function) CREATE OR REPLACE FUNCTION மூலம் ஒரு விருப்பத்தேர்வு அளவுருவை (optional argument) சேர்த்த பிறகு, நேரடிப் பயன்பாட்டில் உள்ள (production) PostgreSQL deployment செயலிழந்தது. இந்த மாற்றம் ஒரே பெயரில் இரண்டு செயல்பாடுகளை உருவாக்கியது, இதனால் தரவுத்தளம் “function is not unique” என்ற பிழையைத் திருப்பியளித்தது மற்றும் API ஒரு 400 பிழையை வெளியிட்டது. ஒரு சிறிய இடமாற்றத் தவறு (migration mistake) எவ்வாறு ஒரு நேரடி ஸ்கீமாவை (live schema) அமைதியுடன் சிதைக்கக்கூடும் என்பதையும், குறியீடு மட்டத்திலான சரிபார்ப்புகள் மட்டுமே போதுமானதல்ல என்பதையும் இந்தச் சம்பவம் காட்டுகிறது.
என்ன தவறு நடந்தது
ஒரு சேமிக்கப்பட்ட நடைமுறையை (stored procedure) கூடுதல், விருப்பத்தேர்வு அளவுருவுடன் நீட்டிக்க வேண்டியிருந்தது அந்தத் குழுவிற்கு. பழைய வரையறையை (definition) இது மாற்றியமைக்கும் என்று கருதி அவர்கள் CREATE OR REPLACE FUNCTION … என்பதை இயக்கினர். முழுமையான அளவுருப் பட்டியல் (argument list) சரியாகப் பொருந்தும் போது மட்டுமே PostgreSQL ஒரு செயல்பாட்டை மாற்றியமைக்கும். கையொப்பத்தை (signature) மாற்றுவது ஒரு புதிய செயல்பாட்டுப் பதிவை உருவாக்கும், அதே சமயம் அசல் பதிவை மாற்றாமல் அப்படியே விட்டுவிடும்.
புதிய அளவுருவிற்கு ஒரு இயல்புநிலை மதிப்பு (default value) இருந்ததால், பழைய அளவுரு எண்ணிக்கையை வழங்கிய அழைப்பாளர்கள் (callers) இரண்டு வரையறைகளுடனும் பொருந்தக்கூடும். எந்த ஒன்றைத் தொடங்குவது என்று PostgreSQL-ஆல் தீர்மானிக்க முடியவில்லை, இதனால் “function is not unique” என்ற பிழை ஏற்பட்டது, இது API-லிருந்து 400 பிழையாக வெளிப்பட்டது.
குறியீடு களஞ்சியம் (code repository) ஒரு ஒற்றை வரையறையையே காட்டியது, மேலும் மூலக் கட்டமைப்பை (source tree) ஸ்கேன் செய்த ஒரு தனிப்பயன் ஸ்கிரிப்ட் எந்த நகல்களையும் (duplicates) கண்டறியவில்லை. அந்த நகல் தரவுத்தளத்தில் மட்டுமே இருந்தது, ஒரு பழைய இடமாற்றக் கோப்பு (migration file) சர்வரில் மீண்டும் இயக்கப்பட்டபோது அது உருவானது.
இடமாற்றம் ஏன் தப்பியது
விருப்பத்தேர்வு அளவுருவைச் சேர்த்த இடமாற்றம் (migration) வெறுமனே CREATE OR REPLACE FUNCTION என்பதை இயக்கினது. அந்த இடமாற்றம் இரண்டாவது முறை இயங்கியபோது—ஒருவேளை ரத்து செய்த பிறகு (rollback) அல்லது மீண்டும் வரிசைப்படுத்தும்போது (repeat deployment)—தரவுத்தளம் அந்த கட்டளையை "தற்போதுள்ளதை மாற்றவும்" என்பதற்குப் பதிலாக "ஒரு புதிய ஓவர்லோட்-ஐச் சேர்க்கவும்" (add a new overload) என்று கருதியது. அந்த இடமாற்றம் அதன் விளைவு நிலையை (resulting state) சரிபார்க்கவில்லை, எனவே அந்த நகல் கவனிக்கப்படாமல் நீடித்தது.
களஞ்சியத்தைச் சரிபார்த்த ஸ்கிரிப்ட் மூலக் கோப்புகளை மட்டுமே ஆய்வு செய்தது, நேரடி ஸ்கீமாவை அல்ல. அது முன் கதவைப் பார்த்துக் கொண்டிருந்தது, ஆனால் பிழை பின் கதவு வழியாக நுழைந்தது.
இதன் பாதிப்புகள்
ஒரே ஒரு தெளிவற்ற செயல்பாடு (ambiguous function), அதைச் சார்ந்திருக்கும் எந்தவொரு சேவையையும் முடக்கிவிடும். செயல்பாடுகளின் எண்ணிக்கை தவறாக இருந்தால் பரிவர்த்தனையைத் திரும்பப் பெறுவது (rolling back the transaction) மற்றும் ஸ்கீமா கேச்-ஐ (schema cache) மீண்டும் ஏற்றத் தெரிவிப்பது போன்ற நடவடிக்கைகளே இதற்கான தீர்வாக அமைந்தது.
இடமாற்றங்களைப் பாதுகாப்பது எப்படி
குழுவினர் இடமாற்றத்தை தெளிவான சரிபார்ப்புகளுடன் மீண்டும் கட்டமைத்தனர், அதை ஒரு சுய-உறுதிப்படுத்தும் செயல்பாடாக (self-asserting operation) மாற்றினர்:
- ஒரு பரிவர்த்தனையைத் தொடங்குங்கள் (Start a transaction), இதனால் ஏதேனும் தோல்வி ஏற்பட்டால் முழு மாற்றமும் ரத்து செய்யப்படும்.
- பழைய செயல்பாட்டைத் தெளிவாக நீக்குங்கள் (Drop the old function explicitly), புதிய பதிப்பை உருவாக்குவதற்கு முன், ஒரே ஒரு வரையறை மட்டுமே இருப்பதை இது உறுதி செய்யும்.
- புதிய செயல்பாட்டை உருவாக்குங்கள் (Create the new function), தேவையான கையொப்பத்துடன் (signature).
- செயல்பாடுகளின் எண்ணிக்கையை எண்ணுங்கள் (Count the functions),
pg_catalog-இல் கொடுக்கப்பட்ட பெயருடைய செயல்பாடுகளின் எண்ணிக்கையை எண்ணி, அது சரியாக ஒன்றுதானா என்பதைச் சரிபார்க்கவும். - பரிவர்த்தனையைத் திரும்பப் பெறுங்கள் (Roll back), எண்ணிக்கை மாறினால், நகல் நீடித்திருப்பதைத் தடுக்க பரிவர்த்தனையை ரத்து செய்யவும்.
- ஸ்கீமா கேச்-ஐத் தெரிவிக்கவும் (Notify the schema cache), அடுத்தடுத்த வினவல்கள் (queries) புதுப்பிக்கப்பட்ட வரையறையைப் பார்ப்பதை உறுதி செய்ய அதை மீண்டும் ஏற்றத் தெரிவிக்கவும்.
குறியீடு சரியானது என்று கருதுவதற்குப் பதிலாக, தரவுத்தளத்திடம் “என்ன செயல்பாடுகள் உள்ளன?” என்று கேட்பதன் மூலம், இடமாற்றம் மீண்டும் மீண்டும் இயங்குதல், பகுதி வரிசைப்படுத்தல்கள் அல்லது கைமுறைத் திருத்தங்கள் ஆகியவற்றிற்கு எதிராக நம்பகமானதாக மாறுகிறது.
எதிர்வாதம்: வசதி vs. பாதுகாப்பு
CREATE OR REPLACE FUNCTION என்பது டெவலப்பர்கள் தனித்தனியான 'drop' அறிக்கைகளை எழுதாமல் விரைவாகச் செயல்பட அனுமதிக்கிறது என்பதால் கவர்ச்சிகரமானது. இடமாற்றங்கள் ஒருமுறை மட்டுமே இயங்கி மீண்டும் இயங்காத சூழல்களில், இந்த குறுக்குவழி நன்றாக வேலை செய்யும். ஆனால் இடமாற்றங்கள் மீண்டும் இயக்கப்படும்போது—அதாவது டெஸ்ட் தரவுத்தளங்களை ரீசெட் செய்யும் CI 파ய்ப்லைன்கள், தானியங்கி ரத்து செய்தல்கள் (automated rollbacks) அல்லது ப்ரொடக்ஷனில் கைமுறையாக மீண்டும் பயன்படுத்துதல் ஆகியவற்றின் காரணமாக—அபாயம் ஏற்படுகிறது.
முக்கியக் கருத்து
CREATE OR REPLACE மூலம் ஒரு செயல்பாட்டின் கையொப்பத்தை மாற்றுவது மாற்றத்தை உறுதிப்படுத்தாது—அளவுருப் பட்டியல் வேறுபட்டால் PostgreSQL அமைதியுடன் ஒரு ஓவர்லோட்டை உருவாக்கும். இடமாற்றங்களைச் சார்ந்திருக்கும் ப்ரொடக்ஷன் சூழல்கள், மூலக் குறியீட்டை மட்டும் பார்க்காமல், அதன் விளைவு ஸ்கீமாவைச் சரிபார்க்க வேண்டும். தெளிவான 'drops', பரிவர்த்தனைச் சரிபார்ப்புகள் மற்றும் இடமாற்றத்திற்குப் பிந்தைய உறுதிப்படுத்தல்களைச் சேர்ப்பது, ஒரு வசதியான குறுக்குவழியை நம்பகமான மற்றும் மீண்டும் செய்யக்கூடிய செயல்முறையாக மாற்றுகிறது.
