Database
 sql >> डेटाबेस >  >> RDS >> Database

वर्ष 2038 की समस्या क्या है?

वर्ष 2038 की समस्या (जिसे Y2K38 बग भी कहा जाता है) एक ऐसी समस्या को संदर्भित करता है जो कुछ कंप्यूटर सिस्टम 2038-01-19 03:14:07 से पहले के समय से निपटने के दौरान सामना कर सकते हैं।

कई कंप्यूटर सिस्टम, जैसे कि यूनिक्स और यूनिक्स-आधारित सिस्टम, ग्रेगोरियन कैलेंडर का उपयोग करके समय की गणना नहीं करते हैं। वे 1 जनवरी 1970 से सेकंड की संख्या के रूप में समय की गणना करते हैं। इसलिए, इन प्रणालियों में, समय को एक बड़ी संख्या के रूप में दर्शाया जाता है (अर्थात 1970-01-01 00:00:00 के बाद से पारित सेकंड की संख्या)। इसे आमतौर पर एपोच टाइम, यूनिक्स टाइम, यूनिक्स एपोच टाइम या पॉज़िक्स टाइम के रूप में जाना जाता है। जैसा कि मैंने इसे लिखा है, यूनिक्स का समय 1560913841 है। और जैसे ही मैं यह अगली पंक्ति लिखता हूं, यूनिक्स का समय बढ़कर 1560913879 हो गया है।

2038 समस्या इस तथ्य के कारण है कि कई सिस्टम इस संख्या को एक हस्ताक्षरित 32-बिट बाइनरी पूर्णांक के रूप में संग्रहीत करते हैं। एक हस्ताक्षरित 32-बिट पूर्णांक की सीमा -2,147,483,648 से 2,147,483,647 है। इसका मतलब है कि नवीनतम युग का समय 2147483647 है। यह मंगलवार, 19 जनवरी 2038 को 03:14:07 बजे होगा।

उसके बाद, परिणाम काफी हद तक सिस्टम पर निर्भर करेगा। कई प्रणालियों में, एक पूर्णांक अतिप्रवाह होगा, और बाद में किसी भी समय को चारों ओर लपेटा जाएगा और आंतरिक रूप से एक नकारात्मक संख्या के रूप में संग्रहीत किया जाएगा। नतीजा यह है कि एक सेकंड बाद, समय की व्याख्या 19 जनवरी 2038 के बजाय 13 दिसंबर 1901 को की जाएगी।

हालाँकि, आप उपयोग में आने वाले एप्लिकेशन के आधार पर अलग-अलग परिणामों के साथ समाप्त हो सकते हैं। भले ही आपके ऑपरेटिंग सिस्टम में कोई समस्या न हो, फिर भी आपके अपने कोड में समस्या हो सकती है। उदाहरण के लिए, यदि आपने यूनिक्स समय वापस करने के लिए कस्टम कोड लिखा है, और आप इसे एक हस्ताक्षरित 4 बाइट पूर्णांक में संग्रहीत करते हैं, तो आपको समस्या होगी। ऐसे मामलों में, 8 बाइट पूर्णांक का उपयोग करने के लिए कोड को फिर से लिखना आपको बस इतना करना होगा।

यह देखते हुए कि यह वेबसाइट डेटाबेस के बारे में है, यहाँ कुछ डेटाबेस उदाहरण हैं।

उदाहरण 1 - MySQL

MySQL में, TIMESTAMP डेटा प्रकार '1970-01-01 00:00:01.000000' UTC से '2038-01-19 03:14:07.999999' तक दिनांक/समय का समर्थन करता है। इसलिए, आप कह सकते हैं कि इस डेटा प्रकार का उपयोग करने वाले किसी भी डेटाबेस में Y2K38 बग है।

MySQL में एक इनबिल्ट फंक्शन भी है जिसे UNIX_TIMESTAMP() . कहा जाता है जो, जैसा कि आप उम्मीद कर सकते हैं, यूनिक्स टाइमस्टैम्प लौटाता है।

UNIX_TIMESTAMP() फ़ंक्शन एक वैकल्पिक तर्क स्वीकार करता है जो आपको यूनिक्स समय के लिए उपयोग करने के लिए एक तिथि निर्दिष्ट करने की अनुमति देता है (यानी '1970-01-01 00:00:00' यूटीसी से आपके द्वारा निर्दिष्ट समय तक सेकंड की संख्या)। तर्क मानों की मान्य श्रेणी TIMESTAMP . के समान है डेटा प्रकार, जो '1970-01-01 00:00:01.000000' यूटीसी से '2038-01-19 03:14:07.999999' यूटीसी है। यदि आप इस फ़ंक्शन के लिए एक आउट-ऑफ-रेंज दिनांक पास करते हैं, तो यह 0 लौटाता है ।

यदि आप '2038-01-19 03:14:07.999999999999999999999999999999999999999999 पहले तक यूनिक्स समय को वापस करने के लिए इस फ़ंक्शन का उपयोग करने का प्रयास करते हैं तो क्या होता है:

SELECT UNIX_TIMESTAMP('2038-01-20') Result;

परिणाम:

+--------+
| Result |
+--------+
|      0 |
+--------+

हमें 0 मिलता है क्योंकि दिनांक तर्क समर्थित सीमा से बाहर है।

2005 में MySQL टीम के लिए एक संबंधित बग रिपोर्ट उठाई गई थी (हालाँकि कुछ विशिष्टताएँ भिन्न प्रतीत होती हैं), और इस लेखन के रूप में, अभी भी संबोधित नहीं किया गया है।

इसी तरह का एक मुद्दा TIMESTAMP . के साथ सीमाओं को संबोधित करने के लिए भी उठाया गया था डेटा प्रकार, जिसे अभी भी संबोधित किया जाना है।

उदाहरण 2 - SQL सर्वर

SQL सर्वर में वर्तमान में MySQL के UNIX_TIMESTAMP के बराबर नहीं है समारोह। इसलिए, यदि आपको युग का समय वापस करने की आवश्यकता है, तो आपको कुछ ऐसा करने की आवश्यकता होगी:

SELECT DATEDIFF(SECOND,'1970-01-01', GETUTCDATE());

यह 2038 की समस्या से पहले की तारीखों के लिए ठीक है। उस तारीख के बाद, आपको समस्याएं होंगी, क्योंकि DATEDIFF() फ़ंक्शन परिणाम को int . के रूप में लौटाता है डेटा प्रकार। इंट डेटा प्रकार की सीमा -2^31 (-2,147,483,648) से 2^31-1 (2,147,483,647) तक होती है।

अगर मैं '2038-01-19 03:14:07' के बाद के समय को वापस करने की कोशिश करता हूं तो यहां क्या होता है:

SELECT DATEDIFF(SECOND,'1970-01-01', '2038-01-19 03:14:08') AS 'Result';

परिणाम:

The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.

सौभाग्य से, एक DATEDIFF_BIG() भी है फ़ंक्शन, जो बिल्कुल वही काम करता है, सिवाय इसके कि यह परिणाम को बिगिंट . के रूप में लौटाता है डेटा प्रकार।

इसलिए हम इस समस्या को दूर करने के लिए पिछले उदाहरण को निम्नलिखित में फिर से लिख सकते हैं:

SELECT DATEDIFF_BIG(SECOND,'1970-01-01 00:00:00', '2038-01-19 03:14:08') AS 'Result';

परिणाम:

+------------+
| Result     |
|------------|
| 2147483648 |
+------------+

बिगिंट डेटा प्रकार 8 बाइट्स का उपयोग करता है (int . के लिए 4 बाइट्स के विपरीत) ), इसलिए आपको यह तय करना होगा कि DATEDIFF_BIG() . पर स्विच करना है या नहीं अभी या बाद में। यदि आपका आवेदन भविष्य की तारीखों से संबंधित है, तो इसे बाद में करने से पहले करना समझदारी हो सकती है।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. चाकू

  2. टी-एसक्यूएल मंगलवार #106 :ट्रिगर्स के बजाय

  3. वेबसाइट के प्रदर्शन को बेहतर बनाने के लिए डेटाबेस कॉल कम करें

  4. Sys.dm_exec_requests की मूल बातें

  5. Kubeadm का उपयोग करके Kubernetes कैसे स्थापित करें