ਇੱਕ ਬਿਨਾਂ ਇੰਡੈਕਸ ਵਾਲੇ ਕਾਲਮ ਨੇ ਸਾਡੇ ਡਾਟਾਬੇਸ ਨੂੰ ਕਿਵੇਂ ਖਤਮ ਕਰ ਦਿੱਤਾ

ਇੱਕ ਗੁੰਮ ਹੋਏ ਇੰਡੈਕਸ ਨੇ 8 ms ਦੀ API ਨੂੰ 8-ਸਕਿੰਟ ਦੇ ਡਰਾਉਣੇ ਸੁਪਨੇ ਵਿੱਚ ਬਦਲ ਦਿੱਤਾ।

ਅਸੀਂ ਇੱਕ ਵੱਡੇ ਰਿਲੀਜ਼ ਤੋਂ ਪਹਿਲਾਂ ਲੋਡ ਟੈਸਟ (load test) ਕੀਤਾ। 100 ਰਿਕਾਰਡਾਂ ਦੇ ਨਾਲ ਲੋਕਲ ਡਿਵੈਲਪਮੈਂਟ ਵਧੀਆ ਚੱਲ ਰਹੀ ਸੀ। ਫਿਰ ਅਸੀਂ ਪ੍ਰੋਡਕਸ਼ਨ-ਸਾਈਜ਼ਡ ਡਾਟਾ ਵਿੱਚ 1.5 ਮਿਲੀਅਨ ਰੋਅਜ਼ (rows) 'ਤੇ 500 ਯੂਜ਼ਰਾਂ ਦਾ ਸਿਮੂਲੇਸ਼ਨ ਕੀਤਾ।

ਨਤੀਜੇ ਬਹੁਤ ਮਾੜੇ ਸਨ:

  • API ਰਿਸਪਾਂਸ ਸਮਾਂ 45 ms ਤੋਂ ਵਧ ਕੇ 8,000 ms ਹੋ ਗਿਆ।
  • ਡਾਟਾਬੇਸ CPU 100 % ਤੱਕ ਪਹੁੰਚ ਗਿਆ।
  • ਕਨੈਕਸ਼ਨ ਪੂਲ (connection pools) ਖਤਮ ਹੋ ਗਏ, ਜਿਸ ਨਾਲ ਟਾਈਮਆਊਟ (timeout) ਗਲਤੀਆਂ ਆਉਣ ਲੱਗੀਆਂ।

ਅਸੀਂ ਸਲੋ-ਕੁਐਰੀ ਲੌਗ (slow-query log) ਦੀ ਜਾਂਚ ਕੀਤੀ ਅਤੇ ਇੱਕ ਅਜਿਹਾ ਐਂਡਪੁਆਇੰਟ (endpoint) ਲੱਭਿਆ ਜੋ user ID ਅਤੇ status ਰਾਹੀਂ ਆਰਡਰ ਹਿਸਟਰੀ ਫੈਚ ਕਰ ਰਿਹਾ ਸੀ।

PostgreSQL 'ਤੇ EXPLAIN ANALYZE ਚਲਾਉਣ 'ਤੇ ਇੱਕ Sequential Scan ਦਿਖਾਈ ਦਿੱਤਾ। ਇੰਜਣ ਹਰ ਰਿਕਵੈਸਟ ਲਈ ਸਾਰੀਆਂ 1.5 ਮਿਲੀਅਨ ਰੋਅਜ਼ ਨੂੰ ਪੜ੍ਹ ਰਿਹਾ ਸੀ ਕਿਉਂਕਿ user_id 'ਤੇ ਕੋਈ ਇੰਡੈਕਸ ਨਹੀਂ ਸੀ।

100 ਇਕਸਾਰ (concurrent) ਰਿਕਵੈਸਟਾਂ ਦੇ ਨਾਲ, ਇਸਨੇ ਇੱਕੋ ਵਾਰ ਵਿੱਚ 150 ਮਿਲੀਅਨ ਰੋਅਜ਼ ਨੂੰ ਸਕੈਨ ਕੀਤਾ।

ਇਸਦਾ ਹੱਲ ਲੱਗਣ ਵਿੱਚ ਪੰਜ ਮਿੰਟ ਲੱਗੇ।

user_id 'ਤੇ ਇੱਕ ਸਾਧਾਰਨ ਇੰਡੈਕਸ ਦੀ ਬਜਾਏ, ਅਸੀਂ (user_id, status, created_at DESC) 'ਤੇ ਇੱਕ ਕੰਪੋਜ਼ਿਟ ਇੰਡੈਕਸ (composite index) ਬਣਾਇਆ। ਇਸ ਨਾਲ ਡਾਟਾਬੇਸ ਨੂੰ ਇਹ ਸਹੂਲਤ ਮਿਲੀ:

  • user_id ਰਾਹੀਂ ਫਿਲਟਰ ਕਰਨਾ।
  • status ਰਾਹੀਂ ਫਿਲਟਰ ਕਰਨਾ।
  • ਤੁਰੰਤ ਨਵੀਆਂ ਰੋਅਜ਼ (rows) ਵਾਪਸ ਕਰਨਾ।
  • ਵਾਧੂ ਸੌਰਟਿੰਗ ਸਟੈਪਸ ਨੂੰ ਛੱਡਣਾ।

ਅਸੀਂ CREATE INDEX CONCURRENTLY ਦੀ ਵਰਤੋਂ ਕੀਤੀ ਤਾਂ ਜੋ ਕਾਰਵਾਈ ਦੌਰਾਨ ਟੇਬਲ ਅਨਲੌਕ (unlocked) ਰਹੇ।

ਹੱਲ ਤੋਂ ਬਾਅਦ:

  • ਕੁਐਰੀ ਸਮਾਂ 8,150 ms ਤੋਂ ਘਟ ਕੇ 0.14 ms ਰਹਿ ਗਿਆ।
  • API ਲੈਟੈਂਸੀ (latency) 8 ਸਕਿੰਟਾਂ ਤੋਂ ਘਟ ਕੇ 12 ms ਹੋ ਗਈ।
  • CPU ਦੀ ਵਰਤੋਂ 100 % ਤੋਂ ਘਟ ਕੇ 8 % ਤੋਂ ਵੀ ਘੱਟ ਹੋ ਗਈ।

ਸਿੱਖੇ ਗਏ ਸਬਕ:

  • ਲੋਕਲ ਟੈਸਟਿੰਗ ਭਰਮਾਊ ਹੋ ਸਕਦੀ ਹੈ; 100 ਰੋਅਜ਼ ਮਿਲੀਅਨ ਦੀ ਨੁਮਾਇੰਦਗੀ ਨਹੀਂ ਕਰਦੀਆਂ।
  • ਆਪਣੀਆਂ ਫੋਰਨ ਕੀਜ਼ (foreign keys) ਨੂੰ ਇੰਡੈਕਸ ਕਰੋ—ਜ਼ਿਆਦਾਤਰ ORMs ਇਸ ਨੂੰ ਛੱਡ ਦਿੰਦੇ ਹਨ।
  • ਹੋਰ ਹਾਰਡਵੇਅਰ ਖਰੀਦਣ ਤੋਂ ਪਹਿਲਾਂ EXPLAIN ANALYZE ਚਲਾਓ।
  • ਇੰਡੈਕਸਾਂ ਨੂੰ ਉਨ੍ਹਾਂ ਕੁਐਰੀਆਂ ਦੇ ਆਧਾਰ 'ਤੇ ਡਿਜ਼ਾਈਨ ਕਰੋ ਜੋ ਤੁਸੀਂ ਅਸਲ ਵਿੱਚ ਚਲਾਉਂਦੇ ਹੋ।

ਪਹਿਲਾਂ ਸਰਵਰਾਂ ਨੂੰ ਸਕੇਲ (scale) ਨਾ ਕਰੋ। ਕੁਐਰੀਆਂ ਨੂੰ ਸਕੇਲ ਕਰੋ।

ਸਰੋਤ: https://dev.to/mia_keller_ffd2584c046ecb/how-an-unindexed-column-silently-killed-our-database-under-load-and-the-5-minute-fix-m32