ਇੱਕ ਪ੍ਰੋਡਕਸ਼ਨ PostgreSQL ਡਿਪਲਾਈਮੈਂਟ ਕ੍ਰੈਸ਼ ਹੋ ਗਿਆ ਜਦੋਂ ਇੱਕ ਡਿਵੈਲਪਰ ਨੇ CREATE OR REPLACE FUNCTION ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਇੱਕ ਮੌਜੂਦਾ ਫੰਕਸ਼ਨ ਵਿੱਚ ਇੱਕ ਵਿਕਲਪਿਕ ਆਰਗੂਮੈਂਟ ਜੋੜ ਦਿੱਤੀ। ਇਸ ਤਬਦੀਲੀ ਕਾਰਨ ਇੱਕੋ ਨਾਮ ਦੇ ਦੋ ਫੰਕਸ਼ਨ ਬਣ ਗਏ, ਜਿਸ ਨਾਲ ਡਾਟਾਬੇਸ ਨੇ “function is not unique” ਐਰਰ ਦਿੱਤਾ ਅਤੇ API ਨੇ 400 ਐਰਰ ਜਾਰੀ ਕੀਤਾ। ਇਹ ਘਟਨਾ ਦਰਸਾਉਂਦੀ ਹੈ ਕਿ ਕਿਵੇਂ ਇੱਕ ਮਾਈਗ੍ਰੇਸ਼ਨ ਦੀ ਇੱਕ ਗਲਤੀ ਚੁੱਪਚਾਪ ਇੱਕ ਲਾਈਵ ਸਕੀਮਾ ਨੂੰ ਖਰਾਬ ਕਰ ਸਕਦੀ ਹੈ ਅਤੇ ਕਿਉਂ ਸਿਰਫ਼ ਕੋਡ-ਲੇਵਲ ਚੈੱਕ ਕਾਫ਼ੀ ਨਹੀਂ ਹਨ।
ਕੀ ਗਲਤ ਹੋਇਆ
ਟੀਮ ਨੂੰ ਇੱਕ ਸਟੋਰਡ ਪ੍ਰੋਸੀਜਰ ਵਿੱਚ ਇੱਕ ਵਾਧੂ, ਵਿਕਲਪਿਕ ਪੈਰਾਮੀਟਰ ਜੋੜਨ ਦੀ ਲੋੜ ਸੀ। ਉਨ੍ਹਾਂ ਨੇ ਇਹ ਮੰਨ ਕੇ CREATE OR REPLACE FUNCTION … ਚਲਾਇਆ ਕਿ ਇਹ ਪੁਰਾਣੀ ਡੈਫੀਨੇਸ਼ਨ ਨੂੰ ਓਵਰਰਾਈਟ ਕਰ ਦੇਵੇਗਾ। PostgreSQL ਫੰਕਸ਼ਨ ਨੂੰ ਉਦੋਂ ਹੀ ਬਦਲਦਾ ਹੈ ਜਦੋਂ ਪੂਰੀ ਆਰਗੂਮੈਂਟ ਲਿਸਟ ਬਿਲਕੁਲ ਮੇਲ ਖਾਂਦੀ ਹੋਵੇ। ਸਿਗਨੇਚਰ (signature) ਬਦਲਣ ਨਾਲ ਇੱਕ ਬਿਲਕੁਲ ਨਵੀਂ ਫੰਕਸ਼ਨ ਐਂਟਰੀ ਬਣ ਜਾਂਦੀ ਹੈ, ਜਦੋਂ ਕਿ ਅਸਲ ਫੰਕਸ਼ਨ ਨੂੰ ਬਿਨਾਂ ਕਿਸੇ ਬਦਲਾਅ ਦੇ ਉਵੇਂ ਹੀ ਛੱਡ ਦਿੱਤਾ ਜਾਂਦਾ ਹੈ।
ਕਿਉਂਕਿ ਨਵੇਂ ਆਰਗੂਮੈਂਟ ਦੀ ਇੱਕ ਡਿਫੌਲਟ ਵੈਲਯੂ ਸੀ, ਇਸ ਲਈ ਉਹ ਕਾਲਰਜ਼ (callers) ਜੋ ਪੁਰਾਣੇ ਆਰਗੂਮੈਂਟਾਂ ਦੀ ਗਿਣਤੀ ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੇ ਸਨ, ਉਹ ਦੋਵਾਂ ਵਿੱਚੋਂ ਕਿਸੇ ਵੀ ਡੈਫੀਨੇਸ਼ਨ ਨਾਲ ਮੇਲ ਖਾ ਸਕਦੇ ਸਨ। PostgreSQL ਇਹ ਫੈਸਲਾ ਨਹੀਂ ਕਰ ਸਕਿਆ ਕਿ ਕਿਸ ਨੂੰ ਇਵੋਕ (invoke) ਕਰਨਾ ਹੈ ਅਤੇ ਉਸਨੇ “function is not unique” ਐਰਰ ਦਿੱਤਾ, ਜੋ API ਤੋਂ 400 ਰਿਸਪਾਂਸ ਵਜੋਂ ਸਾਹਮਣੇ ਆਇਆ।
ਕੋਡ ਰਿਪੋਜ਼ਟਰੀ ਵਿੱਚ ਸਿਰਫ਼ ਇੱਕ ਹੀ ਡੈਫੀਨੇਸ਼ਨ ਦਿਖਾਈ ਦੇ ਰਹੀ ਸੀ, ਅਤੇ ਸੋਰਸ ਟ੍ਰੀ ਨੂੰ ਸਕੈਨ ਕਰਨ ਵਾਲੀ ਇੱਕ ਕਸਟਮ ਸਕ੍ਰਿਪਟ ਨੇ ਕੋਈ ਡੁਪਲੀਕੇਟ ਨਹੀਂ ਦੱਸਿਆ। ਇਹ ਡੁਪਲੀਕੇਟ ਸਿਰਫ਼ ਡਾਟਾਬੇਸ ਵਿੱਚ ਸੀ, ਜੋ ਉਦੋਂ ਪੈਦਾ ਹੋਇਆ ਜਦੋਂ ਸਰਵਰ 'ਤੇ ਇੱਕ ਪੁਰਾਣੀ ਮਾਈਗ੍ਰੇਸ਼ਨ ਫਾਈਲ ਨੂੰ ਦੁਬਾਰਾ ਚਲਾਇਆ ਗਿਆ ਸੀ।
ਮਾਈਗ੍ਰੇਸ਼ਨ ਕਿਉਂ ਰਹਿ ਗਈ
ਵਿਕਲਪਿਕ ਪੈਰਾਮੀਟਰ ਜੋੜਨ ਵਾਲੀ ਮਾਈਗ੍ਰੇਸ਼ਨ ਨੇ ਸਿਰਫ਼ CREATE OR REPLACE FUNCTION ਚਲਾਇਆ ਸੀ। ਜਦੋਂ ਮਾਈਗ੍ਰੇਸ਼ਨ ਦੂਜੀ ਵਾਰ ਚੱਲੀ—ਸ਼ਾਇਦ ਰੋਲਬੈਕ ਤੋਂ ਬਾਅਦ ਜਾਂ ਦੁਬਾਰਾ ਡਿਪਲਾਈਮੈਂਟ ਦੌਰਾਨ—ਡਾਟਾਬੇਸ ਨੇ ਇਸ ਕਮਾਂਡ ਨੂੰ "ਮੌਜੂਦਾ ਨੂੰ ਬਦਲਣ" ਦੀ ਬਜਾਏ "ਇੱਕ ਨਵਾਂ ਓਵਰਲੋਡ ਜੋੜਨ" ਵਜੋਂ ਲਿਆ। ਮਾਈਗ੍ਰੇਸ਼ਨ ਨੇ ਨਤੀਜੇ ਦੀ ਸਥਿਤੀ ਦੀ ਪੁਸ਼ਟੀ ਨਹੀਂ ਕੀਤੀ, ਇਸ ਲਈ ਡੁਪਲੀਕੇਟ ਬਿਨਾਂ ਕਿਸੇ ਨੋਟਿਸ ਦੇ ਬਣਿਆ ਰਿਹਾ।
ਰਿਪੋਜ਼ਟਰੀ ਦੀ ਜਾਂਚ ਕਰਨ ਵਾਲੀ ਸਕ੍ਰਿਪਟ ਨੇ ਸੋਰਸ ਫਾਈਲਾਂ ਦੀ ਜਾਂਚ ਕੀਤੀ ਸੀ, ਲਾਈਵ ਸਕੀਮਾ ਦੀ ਨਹੀਂ। ਉਹ ਅਗਲੇ ਦਰਵਾਜ਼ੇ ਵੱਲ ਦੇਖ ਰਹੀ ਸੀ ਜਦੋਂ ਕਿ ਬੱਗ ਪਿਛਲੇ ਦਰਵਾਜ਼ੇ ਰਾਹੀਂ ਅੰਦਰ ਆ ਗਿਆ ਸੀ।
ਖ਼ਤਰਾ
ਇੱਕ ਅਸਪਸ਼ਟ ਫੰਕਸ਼ਨ ਕਿਸੇ ਵੀ ਸੇਵਾ ਨੂੰ ਡਿਗਨਾ ਸਕਦਾ ਹੈ ਜੋ ਇਸ 'ਤੇ ਨਿਰਭਰ ਕਰਦੀ ਹੈ। ਇਸ ਦਾ ਹੱਲ ਇਹ ਸੀ ਕਿ ਜੇਕਰ ਫੰਕਸ਼ਨ ਦੀ ਗਿਣਤੀ ਗਲਤ ਸੀ ਤਾਂ ਟ੍ਰਾਂਜੈਕਸ਼ਨ ਨੂੰ ਰੋਲਬੈਕ ਕੀਤਾ ਜਾਵੇ ਅਤੇ ਸਕੀਮਾ ਕੈਸ਼ (schema cache) ਨੂੰ ਰੀਲੋਡ ਕਰਨ ਲਈ ਨੋਟੀਫਾਈ ਕੀਤਾ ਜਾਵੇ।
ਮਾਈਗ੍ਰੇਸ਼ਨ ਨੂੰ ਕਿਵੇਂ ਸੁਰੱਖਿਅਤ ਰੱਖਣਾ ਹੈ
ਟੀਮ ਨੇ ਮਾਈਗ੍ਰੇਸ਼ਨ ਨੂੰ ਸਪਸ਼ਟ ਚੈੱਕਾਂ ਦੇ ਨਾਲ ਮੁੜ ਬਣਾਇਆ, ਜਿਸ ਨਾਲ ਇਹ ਇੱਕ ਸਵੈ-ਪੁਸ਼ਟੀਕਰਨ ਵਾਲਾ ਆਪਰੇਸ਼ਨ ਬਣ ਗਿਆ:
- ਟ੍ਰਾਂਜੈਕਸ਼ਨ ਸ਼ੁਰੂ ਕਰੋ ਤਾਂ ਜੋ ਕੋਈ ਵੀ ਅਸਫਲਤਾ ਪੂਰੇ ਬਦਲਾਅ ਨੂੰ ਰੋਲਬੈਕ ਕਰ ਦੇਵੇ।
- ਪੁਰਾਣੇ ਫੰਕਸ਼ਨ ਨੂੰ ਸਪਸ਼ਟ ਰੂਪ ਵਿੱਚ ਡ੍ਰੌਪ ਕਰੋ ਨਵਾਂ ਵਰਜ਼ਨ ਬਣਾਉਣ ਤੋਂ ਪਹਿਲਾਂ, ਇਹ ਯਕੀਨੀ ਬਣਾਉਣ ਲਈ ਕਿ ਸਿਰਫ਼ ਇੱਕ ਹੀ ਡੈਫੀਨੇਸ਼ਨ ਮੌਜੂਦ ਹੈ।
- ਨਵਾਂ ਫੰਕਸ਼ਨ ਬਣਾਓ ਲੋੜੀਂਦੇ ਸਿਗਨੇਚਰ ਦੇ ਨਾਲ।
pg_catalogਵਿੱਚ ਦਿੱਤੇ ਨਾਮ ਦੇ ਫੰਕਸ਼ਨਾਂ ਦੀ ਗਿਣਤੀ ਕਰੋ ਅਤੇ ਪੁਸ਼ਟੀ ਕਰੋ ਕਿ ਗਿਣਤੀ ਬਿਲਕੁਲ ਇੱਕ ਹੈ।- ਜੇਕਰ ਗਿਣਤੀ ਵੱਖਰੀ ਹੁੰਦੀ ਹੈ, ਤਾਂ ਟ੍ਰਾਂਜੈਕਸ਼ਨ ਨੂੰ ਰੋਲ ਬੈਕ ਕਰੋ, ਤਾਂ ਜੋ ਡੁਪਲੀਕੇਟ ਬਣਿਆ ਨਾ ਰਹੇ।
- ਸਕੀਮਾ ਕੈਸ਼ ਨੂੰ ਨੋਟੀਫਾਈ ਕਰੋ ਤਾਂ ਜੋ ਰੀਲੋਡ ਹੋ ਸਕੇ, ਅਤੇ ਇਹ ਯਕੀਨੀ ਬਣਾਇਆ ਜਾ ਸਕੇ ਕਿ ਅਗਲੇਰੀਆਂ ਕੁਏਰੀਆਂ (queries) ਅਪਡੇਟ ਕੀਤੀ ਹੋਈ ਡੈਫੀਨੇਸ਼ਨ ਦੇਖ ਸਕਣ।
ਇਹ ਮੰਨਣ ਦੀ ਬਜਾਏ ਕਿ ਕੋਡ ਸਹੀ ਹੈ, ਡਾਟਾਬੇਸ ਨੂੰ ਇਹ ਪੁੱਛ ਕੇ ਕਿ "ਕਿਹੜੇ ਫੰਕਸ਼ਨ ਮੌਜੂਦ ਹਨ?", ਮਾਈਗ੍ਰੇਸ਼ਨ ਵਾਰ-ਵਾਰ ਚੱਲਣ, ਅਧੂਰੇ ਡਿਪਲਾਈਮੈਂਟ ਜਾਂ ਮੈਨੂਅਲ ਐਡਿਟਸ ਦੇ ਵਿਰੁੱਧ ਭਰੋਸੇਯੋਗ ਬਣ ਜਾਂਦੀ ਹੈ।
ਵਿਰੋਧੀ ਦਲੀਲ: ਸਹੂਲਤ ਬਨਾਮ ਸੁਰੱਖਿਆ
CREATE OR REPLACE FUNCTION ਆਕਰਸ਼ਕ ਹੈ ਕਿਉਂਕਿ ਇਹ ਡਿਵੈਲਪਰਾਂ ਨੂੰ ਵੱਖਰੇ ਡ੍ਰੌਪ ਸਟੇਟਮੈਂਟ ਲਿਖੇ ਬਿਨਾਂ ਤੇਜ਼ੀ ਨਾਲ ਇਟਰੇਟ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਦਿੰਦਾ ਹੈ। ਅਜਿਹੇ ਮਾਹੌਲ ਵਿੱਚ ਜਿੱਥੇ ਮਾਈਗ੍ਰੇਸ਼ਨ ਇੱਕ ਵਾਰ ਚੱਲਦੀ ਹੈ ਅਤੇ ਕਦੇ ਦੁਬਾਰਾ ਨਹੀਂ ਚੱਲਦੀ, ਉੱਥੇ ਇਹ ਸ਼ਾਰਟਕੱਟ ਵਧੀਆ ਕੰਮ ਕਰਦਾ ਹੈ। ਖ਼ਤਰਾ ਉਦੋਂ ਪੈਦਾ ਹੁੰਦਾ ਹੈ ਜਦੋਂ ਮਾਈਗ੍ਰੇਸ਼ਨ ਨੂੰ ਦੁਬਾਰਾ ਚਲਾਇਆ ਜਾਂਦਾ ਹੈ—ਚਾਹੇ ਉਹ CI ਪਾਈਪਲਾਈਨਾਂ ਕਾਰਨ ਹੋਵੇ ਜੋ ਟੈਸਟ ਡਾਟਾਬੇਸ ਨੂੰ ਰੀਸੈੱਟ ਕਰਦੀਆਂ ਹਨ, ਆਟੋਮੇਟਡ ਰੋਲਬੈਕਸ, ਜਾਂ ਪ੍ਰੋਡਕਸ਼ਨ ਵਿੱਚ ਮੈਨੂਅਲ ਰੀ-ਐਪਲੀਕੇਸ਼ਨ ਕਾਰਨ।
ਸਿੱਖਿਆ
CREATE OR REPLACE ਨਾਲ ਫੰਕਸ਼ਨ ਦੇ ਸਿਗਨੇਚਰ ਨੂੰ ਬਦਲਣਾ ਬਦਲਣ ਦੀ ਗਾਰੰਟੀ ਨਹੀਂ ਦਿੰਦਾ—ਜੇਕਰ ਆਰਗੂਮੈਂਟ ਲਿਸਟ ਵੱਖਰੀ ਹੈ ਤਾਂ PostgreSQL ਚੁੱਪਚਾਪ ਇੱਕ ਓਵਰਲੋਡ ਬਣਾ ਦੇਵੇਗਾ। ਉਹ ਪ੍ਰੋਡਕਸ਼ਨ ਮਾਹੌਲ ਜੋ ਮਾਈਗ੍ਰੇਸ਼ਨ 'ਤੇ ਨਿਰਭਰ ਕਰਦੇ ਹਨ, ਉਨ੍ਹਾਂ ਨੂੰ ਸਿਰਫ਼ ਸੋਰਸ ਕੋਡ ਹੀ ਨਹੀਂ, ਸਗੋਂ ਨਤੀਜੇ ਵਾਲੇ ਸਕੀਮਾ ਦੀ ਵੀ ਪੁਸ਼ਟੀ ਕਰਨੀ ਚਾਹੀਦੀ ਹੈ। ਸਪਸ਼ਟ ਡ੍ਰੌਪਸ, ਟ੍ਰਾਂਜੈਕਸ਼ਨਲ ਚੈੱਕਸ, ਅਤੇ ਮਾਈਗ੍ਰੇਸ਼ਨ ਤੋਂ ਬਾਅਦ ਦੇ ਐਸਰਸ਼ਨ (assertions) ਨੂੰ ਸ਼ਾਮਲ ਕਰਨਾ ਇੱਕ ਸੁਵਿਧਾਜਨਕ ਸ਼ਾਰਟਕੱਟ ਨੂੰ ਇੱਕ ਭਰੋਸੇਯੋਗ ਅਤੇ ਦੁਹਰਾਉਣਯੋਗ ਪ੍ਰਕਿਰਿਆ ਵਿੱਚ ਬਦਲ ਦਿੰਦਾ ਹੈ।
